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