1 /* 2 * Qualcomm pm8916 pmic driver 3 * 4 * (C) Copyright 2015 Mateusz Kulikowski <mateusz.kulikowski@gmail.com> 5 * 6 * SPDX-License-Identifier: GPL-2.0+ 7 */ 8 #include <common.h> 9 #include <dm.h> 10 #include <power/pmic.h> 11 #include <spmi/spmi.h> 12 13 #define PID_SHIFT 8 14 #define PID_MASK (0xFF << PID_SHIFT) 15 #define REG_MASK 0xFF 16 17 struct pm8916_priv { 18 uint32_t usid; /* Slave ID on SPMI bus */ 19 }; 20 21 static int pm8916_reg_count(struct udevice *dev) 22 { 23 return 0xFFFF; 24 } 25 26 static int pm8916_write(struct udevice *dev, uint reg, const uint8_t *buff, 27 int len) 28 { 29 struct pm8916_priv *priv = dev_get_priv(dev); 30 31 if (len != 1) 32 return -EINVAL; 33 34 return spmi_reg_write(dev->parent, priv->usid, 35 (reg & PID_MASK) >> PID_SHIFT, reg & REG_MASK, 36 *buff); 37 } 38 39 static int pm8916_read(struct udevice *dev, uint reg, uint8_t *buff, int len) 40 { 41 struct pm8916_priv *priv = dev_get_priv(dev); 42 int val; 43 44 if (len != 1) 45 return -EINVAL; 46 47 val = spmi_reg_read(dev->parent, priv->usid, 48 (reg & PID_MASK) >> PID_SHIFT, reg & REG_MASK); 49 50 if (val < 0) 51 return val; 52 *buff = val; 53 return 0; 54 } 55 56 static struct dm_pmic_ops pm8916_ops = { 57 .reg_count = pm8916_reg_count, 58 .read = pm8916_read, 59 .write = pm8916_write, 60 }; 61 62 static const struct udevice_id pm8916_ids[] = { 63 { .compatible = "qcom,spmi-pmic" }, 64 { } 65 }; 66 67 static int pm8916_probe(struct udevice *dev) 68 { 69 struct pm8916_priv *priv = dev_get_priv(dev); 70 71 priv->usid = dev_read_addr(dev); 72 73 if (priv->usid == FDT_ADDR_T_NONE) 74 return -EINVAL; 75 76 return 0; 77 } 78 79 U_BOOT_DRIVER(pmic_pm8916) = { 80 .name = "pmic_pm8916", 81 .id = UCLASS_PMIC, 82 .of_match = pm8916_ids, 83 .bind = dm_scan_fdt_dev, 84 .probe = pm8916_probe, 85 .ops = &pm8916_ops, 86 .priv_auto_alloc_size = sizeof(struct pm8916_priv), 87 }; 88