This PMIC is connected on SPMI bus so needs SPMI support enabled. Signed-off-by: Mateusz Kulikowski <mateusz.kulikowski@gmail.com> Reviewed-by: Simon Glass <sjg@chromium.org> Tested-by: Simon Glass <sjg@chromium.org>master
parent
5b47271c18
commit
c2f74c8f53
@ -0,0 +1,18 @@ |
||||
Qualcomm pm8916 PMIC |
||||
|
||||
This PMIC is connected using SPMI bus so should be child of SPMI bus controller. |
||||
|
||||
Required properties: |
||||
- compatible: "qcom,spmi-pmic"; |
||||
- reg: SPMI Slave ID, size (ignored) |
||||
- #address-cells: 0x1 (peripheral ID) |
||||
- #size-cells: 0x1 (size of peripheral register space) |
||||
|
||||
Example: |
||||
|
||||
pm8916@0 { |
||||
compatible = "qcom,spmi-pmic"; |
||||
reg = <0x0 0x1>; |
||||
#address-cells = <0x1>; |
||||
#size-cells = <0x1>; |
||||
}; |
@ -0,0 +1,96 @@ |
||||
/*
|
||||
* Qualcomm pm8916 pmic driver |
||||
* |
||||
* (C) Copyright 2015 Mateusz Kulikowski <mateusz.kulikowski@gmail.com> |
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
*/ |
||||
#include <common.h> |
||||
#include <dm.h> |
||||
#include <dm/root.h> |
||||
#include <power/pmic.h> |
||||
#include <spmi/spmi.h> |
||||
|
||||
DECLARE_GLOBAL_DATA_PTR; |
||||
|
||||
#define PID_SHIFT 8 |
||||
#define PID_MASK (0xFF << PID_SHIFT) |
||||
#define REG_MASK 0xFF |
||||
|
||||
struct pm8916_priv { |
||||
uint16_t usid; /* Slave ID on SPMI bus */ |
||||
}; |
||||
|
||||
static int pm8916_reg_count(struct udevice *dev) |
||||
{ |
||||
return 0xFFFF; |
||||
} |
||||
|
||||
static int pm8916_write(struct udevice *dev, uint reg, const uint8_t *buff, |
||||
int len) |
||||
{ |
||||
struct pm8916_priv *priv = dev_get_priv(dev); |
||||
|
||||
if (len != 1) |
||||
return -EINVAL; |
||||
|
||||
return spmi_reg_write(dev->parent, priv->usid, |
||||
(reg & PID_MASK) >> PID_SHIFT, reg & REG_MASK, |
||||
*buff); |
||||
} |
||||
|
||||
static int pm8916_read(struct udevice *dev, uint reg, uint8_t *buff, int len) |
||||
{ |
||||
struct pm8916_priv *priv = dev_get_priv(dev); |
||||
int val; |
||||
|
||||
if (len != 1) |
||||
return -EINVAL; |
||||
|
||||
val = spmi_reg_read(dev->parent, priv->usid, |
||||
(reg & PID_MASK) >> PID_SHIFT, reg & REG_MASK); |
||||
|
||||
if (val < 0) |
||||
return val; |
||||
*buff = val; |
||||
return 0; |
||||
} |
||||
|
||||
static struct dm_pmic_ops pm8916_ops = { |
||||
.reg_count = pm8916_reg_count, |
||||
.read = pm8916_read, |
||||
.write = pm8916_write, |
||||
}; |
||||
|
||||
static const struct udevice_id pm8916_ids[] = { |
||||
{ .compatible = "qcom,spmi-pmic" }, |
||||
{ } |
||||
}; |
||||
|
||||
static int pm8916_probe(struct udevice *dev) |
||||
{ |
||||
struct pm8916_priv *priv = dev_get_priv(dev); |
||||
|
||||
priv->usid = dev_get_addr(dev); |
||||
|
||||
if (priv->usid == FDT_ADDR_T_NONE) |
||||
return -EINVAL; |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
|
||||
static int pm8916_bind(struct udevice *dev) |
||||
{ |
||||
return dm_scan_fdt_node(dev, gd->fdt_blob, dev->of_offset, false); |
||||
} |
||||
|
||||
U_BOOT_DRIVER(pmic_pm8916) = { |
||||
.name = "pmic_pm8916", |
||||
.id = UCLASS_PMIC, |
||||
.of_match = pm8916_ids, |
||||
.bind = pm8916_bind, |
||||
.probe = pm8916_probe, |
||||
.ops = &pm8916_ops, |
||||
.priv_auto_alloc_size = sizeof(struct pm8916_priv), |
||||
}; |
Loading…
Reference in new issue