1*c57a226aSLukasz Majewski // SPDX-License-Identifier: GPL-2.0+ 2*c57a226aSLukasz Majewski /* 3*c57a226aSLukasz Majewski * Copyright (C) 2018 4*c57a226aSLukasz Majewski * Lukasz Majewski, DENX Software Engineering, lukma@denx.de 5*c57a226aSLukasz Majewski * 6*c57a226aSLukasz Majewski */ 7*c57a226aSLukasz Majewski 8*c57a226aSLukasz Majewski #include <common.h> 9*c57a226aSLukasz Majewski #include <dm.h> 10*c57a226aSLukasz Majewski #include <errno.h> 11*c57a226aSLukasz Majewski #include <fsl_pmic.h> 12*c57a226aSLukasz Majewski #include <i2c.h> 13*c57a226aSLukasz Majewski #include <power/pmic.h> 14*c57a226aSLukasz Majewski 15*c57a226aSLukasz Majewski DECLARE_GLOBAL_DATA_PTR; 16*c57a226aSLukasz Majewski 17*c57a226aSLukasz Majewski static int mc34708_reg_count(struct udevice *dev) 18*c57a226aSLukasz Majewski { 19*c57a226aSLukasz Majewski return PMIC_NUM_OF_REGS; 20*c57a226aSLukasz Majewski } 21*c57a226aSLukasz Majewski 22*c57a226aSLukasz Majewski static int mc34708_write(struct udevice *dev, uint reg, const u8 *buff, 23*c57a226aSLukasz Majewski int len) 24*c57a226aSLukasz Majewski { 25*c57a226aSLukasz Majewski u8 buf[3] = { 0 }; 26*c57a226aSLukasz Majewski int ret; 27*c57a226aSLukasz Majewski 28*c57a226aSLukasz Majewski if (len != MC34708_TRANSFER_SIZE) 29*c57a226aSLukasz Majewski return -EINVAL; 30*c57a226aSLukasz Majewski 31*c57a226aSLukasz Majewski /* 32*c57a226aSLukasz Majewski * The MC34708 sends data with big endian format, hence we need to 33*c57a226aSLukasz Majewski * perform manual byte swap. 34*c57a226aSLukasz Majewski */ 35*c57a226aSLukasz Majewski buf[0] = buff[2]; 36*c57a226aSLukasz Majewski buf[1] = buff[1]; 37*c57a226aSLukasz Majewski buf[2] = buff[0]; 38*c57a226aSLukasz Majewski 39*c57a226aSLukasz Majewski ret = dm_i2c_write(dev, reg, buf, len); 40*c57a226aSLukasz Majewski if (ret) 41*c57a226aSLukasz Majewski printf("write error to device: %p register: %#x!", dev, reg); 42*c57a226aSLukasz Majewski 43*c57a226aSLukasz Majewski return ret; 44*c57a226aSLukasz Majewski } 45*c57a226aSLukasz Majewski 46*c57a226aSLukasz Majewski static int mc34708_read(struct udevice *dev, uint reg, u8 *buff, int len) 47*c57a226aSLukasz Majewski { 48*c57a226aSLukasz Majewski u8 buf[3] = { 0 }; 49*c57a226aSLukasz Majewski int ret; 50*c57a226aSLukasz Majewski 51*c57a226aSLukasz Majewski if (len != MC34708_TRANSFER_SIZE) 52*c57a226aSLukasz Majewski return -EINVAL; 53*c57a226aSLukasz Majewski 54*c57a226aSLukasz Majewski ret = dm_i2c_read(dev, reg, buf, len); 55*c57a226aSLukasz Majewski if (ret) 56*c57a226aSLukasz Majewski printf("read error from device: %p register: %#x!", dev, reg); 57*c57a226aSLukasz Majewski 58*c57a226aSLukasz Majewski buff[0] = buf[2]; 59*c57a226aSLukasz Majewski buff[1] = buf[1]; 60*c57a226aSLukasz Majewski buff[2] = buf[0]; 61*c57a226aSLukasz Majewski 62*c57a226aSLukasz Majewski return ret; 63*c57a226aSLukasz Majewski } 64*c57a226aSLukasz Majewski 65*c57a226aSLukasz Majewski static int mc34708_probe(struct udevice *dev) 66*c57a226aSLukasz Majewski { 67*c57a226aSLukasz Majewski struct uc_pmic_priv *priv = dev_get_uclass_priv(dev); 68*c57a226aSLukasz Majewski 69*c57a226aSLukasz Majewski priv->trans_len = MC34708_TRANSFER_SIZE; 70*c57a226aSLukasz Majewski 71*c57a226aSLukasz Majewski /* 72*c57a226aSLukasz Majewski * Handle PMIC Errata 37: APS mode not fully functional, 73*c57a226aSLukasz Majewski * use explicit PWM or PFM instead 74*c57a226aSLukasz Majewski */ 75*c57a226aSLukasz Majewski pmic_clrsetbits(dev, MC34708_REG_SW12_OPMODE, 76*c57a226aSLukasz Majewski MC34708_SW1AMODE_MASK | MC34708_SW2MODE_MASK, 77*c57a226aSLukasz Majewski SW_MODE_PWMPWM | (SW_MODE_PWMPWM << 14u)); 78*c57a226aSLukasz Majewski 79*c57a226aSLukasz Majewski pmic_clrsetbits(dev, MC34708_REG_SW345_OPMODE, 80*c57a226aSLukasz Majewski MC34708_SW3MODE_MASK | MC34708_SW4AMODE_MASK | 81*c57a226aSLukasz Majewski MC34708_SW4BMODE_MASK | MC34708_SW5MODE_MASK, 82*c57a226aSLukasz Majewski SW_MODE_PWMPWM | (SW_MODE_PWMPWM << 6u) | 83*c57a226aSLukasz Majewski (SW_MODE_PWMPWM << 12u) | (SW_MODE_PWMPWM << 18u)); 84*c57a226aSLukasz Majewski 85*c57a226aSLukasz Majewski return 0; 86*c57a226aSLukasz Majewski } 87*c57a226aSLukasz Majewski 88*c57a226aSLukasz Majewski static struct dm_pmic_ops mc34708_ops = { 89*c57a226aSLukasz Majewski .reg_count = mc34708_reg_count, 90*c57a226aSLukasz Majewski .read = mc34708_read, 91*c57a226aSLukasz Majewski .write = mc34708_write, 92*c57a226aSLukasz Majewski }; 93*c57a226aSLukasz Majewski 94*c57a226aSLukasz Majewski static const struct udevice_id mc34708_ids[] = { 95*c57a226aSLukasz Majewski { .compatible = "fsl,mc34708" }, 96*c57a226aSLukasz Majewski { } 97*c57a226aSLukasz Majewski }; 98*c57a226aSLukasz Majewski 99*c57a226aSLukasz Majewski U_BOOT_DRIVER(pmic_mc34708) = { 100*c57a226aSLukasz Majewski .name = "mc34708_pmic", 101*c57a226aSLukasz Majewski .id = UCLASS_PMIC, 102*c57a226aSLukasz Majewski .of_match = mc34708_ids, 103*c57a226aSLukasz Majewski .probe = mc34708_probe, 104*c57a226aSLukasz Majewski .ops = &mc34708_ops, 105*c57a226aSLukasz Majewski }; 106