Łukasz Majewski | 16db062 | 2011-10-06 02:37:34 +0000 | [diff] [blame] | 1 | /* |
Przemyslaw Marczak | 9a8bc95 | 2015-04-20 20:07:41 +0200 | [diff] [blame] | 2 | * Copyright (C) 2014-2015 Samsung Electronics |
| 3 | * Przemyslaw Marczak <p.marczak@samsung.com> |
| 4 | * |
Łukasz Majewski | 1c6dba1 | 2012-11-13 03:21:55 +0000 | [diff] [blame] | 5 | * Copyright (C) 2011-2012 Samsung Electronics |
Łukasz Majewski | 16db062 | 2011-10-06 02:37:34 +0000 | [diff] [blame] | 6 | * Lukasz Majewski <l.majewski@samsung.com> |
| 7 | * |
Wolfgang Denk | d79de1d | 2013-07-08 09:37:19 +0200 | [diff] [blame] | 8 | * SPDX-License-Identifier: GPL-2.0+ |
Łukasz Majewski | 16db062 | 2011-10-06 02:37:34 +0000 | [diff] [blame] | 9 | */ |
| 10 | |
| 11 | #ifndef __CORE_PMIC_H_ |
| 12 | #define __CORE_PMIC_H_ |
| 13 | |
Łukasz Majewski | 1c6dba1 | 2012-11-13 03:21:55 +0000 | [diff] [blame] | 14 | #include <i2c.h> |
Przemyslaw Marczak | 1031498 | 2015-05-13 13:38:26 +0200 | [diff] [blame] | 15 | #include <linux/list.h> |
Łukasz Majewski | 62ecae9 | 2012-11-13 03:22:00 +0000 | [diff] [blame] | 16 | #include <power/power_chrg.h> |
Łukasz Majewski | 1c6dba1 | 2012-11-13 03:21:55 +0000 | [diff] [blame] | 17 | |
Łukasz Majewski | 62ecae9 | 2012-11-13 03:22:00 +0000 | [diff] [blame] | 18 | enum { PMIC_I2C, PMIC_SPI, PMIC_NONE}; |
Przemyslaw Marczak | 9a8bc95 | 2015-04-20 20:07:41 +0200 | [diff] [blame] | 19 | |
| 20 | #ifdef CONFIG_POWER |
Łukasz Majewski | 16db062 | 2011-10-06 02:37:34 +0000 | [diff] [blame] | 21 | enum { I2C_PMIC, I2C_NUM, }; |
| 22 | enum { PMIC_READ, PMIC_WRITE, }; |
Łukasz Majewski | 40f5ca0 | 2012-11-13 03:21:53 +0000 | [diff] [blame] | 23 | enum { PMIC_SENSOR_BYTE_ORDER_LITTLE, PMIC_SENSOR_BYTE_ORDER_BIG, }; |
Łukasz Majewski | 16db062 | 2011-10-06 02:37:34 +0000 | [diff] [blame] | 24 | |
Simon Glass | 05400a6 | 2014-05-20 06:01:35 -0600 | [diff] [blame] | 25 | enum { |
| 26 | PMIC_CHARGER_DISABLE, |
| 27 | PMIC_CHARGER_ENABLE, |
| 28 | }; |
| 29 | |
Łukasz Majewski | 16db062 | 2011-10-06 02:37:34 +0000 | [diff] [blame] | 30 | struct p_i2c { |
| 31 | unsigned char addr; |
| 32 | unsigned char *buf; |
| 33 | unsigned char tx_num; |
| 34 | }; |
| 35 | |
| 36 | struct p_spi { |
| 37 | unsigned int cs; |
| 38 | unsigned int mode; |
| 39 | unsigned int bitlen; |
| 40 | unsigned int clk; |
| 41 | unsigned int flags; |
| 42 | u32 (*prepare_tx)(u32 reg, u32 *val, u32 write); |
| 43 | }; |
| 44 | |
Łukasz Majewski | 62ecae9 | 2012-11-13 03:22:00 +0000 | [diff] [blame] | 45 | struct pmic; |
| 46 | struct power_fg { |
| 47 | int (*fg_battery_check) (struct pmic *p, struct pmic *bat); |
| 48 | int (*fg_battery_update) (struct pmic *p, struct pmic *bat); |
| 49 | }; |
| 50 | |
| 51 | struct power_chrg { |
| 52 | int (*chrg_type) (struct pmic *p); |
| 53 | int (*chrg_bat_present) (struct pmic *p); |
| 54 | int (*chrg_state) (struct pmic *p, int state, int current); |
| 55 | }; |
| 56 | |
| 57 | struct power_battery { |
| 58 | struct battery *bat; |
| 59 | int (*battery_init) (struct pmic *bat, struct pmic *p1, |
| 60 | struct pmic *p2, struct pmic *p3); |
| 61 | int (*battery_charge) (struct pmic *bat); |
| 62 | /* Keep info about power devices involved with battery operation */ |
| 63 | struct pmic *chrg, *fg, *muic; |
| 64 | }; |
| 65 | |
Łukasz Majewski | 16db062 | 2011-10-06 02:37:34 +0000 | [diff] [blame] | 66 | struct pmic { |
| 67 | const char *name; |
| 68 | unsigned char bus; |
| 69 | unsigned char interface; |
Łukasz Majewski | 40f5ca0 | 2012-11-13 03:21:53 +0000 | [diff] [blame] | 70 | unsigned char sensor_byte_order; |
Łukasz Majewski | 1c6dba1 | 2012-11-13 03:21:55 +0000 | [diff] [blame] | 71 | unsigned int number_of_regs; |
Łukasz Majewski | 16db062 | 2011-10-06 02:37:34 +0000 | [diff] [blame] | 72 | union hw { |
| 73 | struct p_i2c i2c; |
| 74 | struct p_spi spi; |
| 75 | } hw; |
Łukasz Majewski | 1c6dba1 | 2012-11-13 03:21:55 +0000 | [diff] [blame] | 76 | |
Łukasz Majewski | 62ecae9 | 2012-11-13 03:22:00 +0000 | [diff] [blame] | 77 | void (*low_power_mode) (void); |
| 78 | struct power_battery *pbat; |
| 79 | struct power_chrg *chrg; |
| 80 | struct power_fg *fg; |
| 81 | |
| 82 | struct pmic *parent; |
Łukasz Majewski | 1c6dba1 | 2012-11-13 03:21:55 +0000 | [diff] [blame] | 83 | struct list_head list; |
Łukasz Majewski | 16db062 | 2011-10-06 02:37:34 +0000 | [diff] [blame] | 84 | }; |
Przemyslaw Marczak | 9a8bc95 | 2015-04-20 20:07:41 +0200 | [diff] [blame] | 85 | #endif /* CONFIG_POWER */ |
| 86 | |
| 87 | #ifdef CONFIG_DM_PMIC |
| 88 | /** |
| 89 | * U-Boot PMIC Framework |
| 90 | * ===================== |
| 91 | * |
Przemyslaw Marczak | 1031498 | 2015-05-13 13:38:26 +0200 | [diff] [blame] | 92 | * UCLASS_PMIC - This is designed to provide an I/O interface for PMIC devices. |
Przemyslaw Marczak | 9a8bc95 | 2015-04-20 20:07:41 +0200 | [diff] [blame] | 93 | * |
| 94 | * For the multi-function PMIC devices, this can be used as parent I/O device |
Przemyslaw Marczak | 1031498 | 2015-05-13 13:38:26 +0200 | [diff] [blame] | 95 | * for each IC's interface. Then, each child uses its parent for read/write. |
Przemyslaw Marczak | 9a8bc95 | 2015-04-20 20:07:41 +0200 | [diff] [blame] | 96 | * |
| 97 | * The driver model tree could look like this: |
| 98 | * |
| 99 | *_ root device |
| 100 | * |_ BUS 0 device (e.g. I2C0) - UCLASS_I2C/SPI/... |
| 101 | * | |_ PMIC device (READ/WRITE ops) - UCLASS_PMIC |
| 102 | * | |_ REGULATOR device (ldo/buck/... ops) - UCLASS_REGULATOR |
| 103 | * | |_ CHARGER device (charger ops) - UCLASS_CHARGER (in the future) |
| 104 | * | |_ MUIC device (microUSB connector ops) - UCLASS_MUIC (in the future) |
| 105 | * | |_ ... |
| 106 | * | |
| 107 | * |_ BUS 1 device (e.g. I2C1) - UCLASS_I2C/SPI/... |
| 108 | * |_ PMIC device (READ/WRITE ops) - UCLASS_PMIC |
| 109 | * |_ RTC device (rtc ops) - UCLASS_RTC (in the future) |
| 110 | * |
| 111 | * We can find two PMIC cases in boards design: |
| 112 | * - single I/O interface |
| 113 | * - multiple I/O interfaces |
Przemyslaw Marczak | 1031498 | 2015-05-13 13:38:26 +0200 | [diff] [blame] | 114 | * We bind a single PMIC device for each interface, to provide an I/O for |
| 115 | * its child devices. And each child usually implements a different function, |
Przemyslaw Marczak | 9a8bc95 | 2015-04-20 20:07:41 +0200 | [diff] [blame] | 116 | * controlled by the same interface. |
| 117 | * |
| 118 | * The binding should be done automatically. If device tree nodes/subnodes are |
| 119 | * proper defined, then: |
| 120 | * |
| 121 | * |_ the ROOT driver will bind the device for I2C/SPI node: |
| 122 | * |_ the I2C/SPI driver should bind a device for pmic node: |
| 123 | * |_ the PMIC driver should bind devices for its childs: |
| 124 | * |_ regulator (child) |
| 125 | * |_ charger (child) |
| 126 | * |_ other (child) |
| 127 | * |
| 128 | * The same for other device nodes, for multi-interface PMIC. |
| 129 | * |
| 130 | * Note: |
| 131 | * Each PMIC interface driver should use a different compatible string. |
| 132 | * |
Przemyslaw Marczak | 1031498 | 2015-05-13 13:38:26 +0200 | [diff] [blame] | 133 | * If a PMIC child device driver needs access the PMIC-specific registers, |
Przemyslaw Marczak | 9a8bc95 | 2015-04-20 20:07:41 +0200 | [diff] [blame] | 134 | * it need know only the register address and the access can be done through |
| 135 | * the parent pmic driver. Like in the example: |
| 136 | * |
| 137 | *_ root driver |
| 138 | * |_ dev: bus I2C0 - UCLASS_I2C |
| 139 | * | |_ dev: my_pmic (read/write) (is parent) - UCLASS_PMIC |
| 140 | * | |_ dev: my_regulator (set value/etc..) (is child) - UCLASS_REGULATOR |
| 141 | * |
| 142 | * To ensure such device relationship, the pmic device driver should also bind |
Przemyslaw Marczak | 1031498 | 2015-05-13 13:38:26 +0200 | [diff] [blame] | 143 | * all its child devices, like in the example below. It can be done by calling |
| 144 | * the 'pmic_bind_children()' - please refer to the function description, which |
| 145 | * can be found in this header file. This function, should be called inside the |
| 146 | * driver's bind() method. |
Przemyslaw Marczak | 9a8bc95 | 2015-04-20 20:07:41 +0200 | [diff] [blame] | 147 | * |
| 148 | * For the example driver, please refer the MAX77686 driver: |
| 149 | * - 'drivers/power/pmic/max77686.c' |
| 150 | */ |
| 151 | |
| 152 | /** |
| 153 | * struct dm_pmic_ops - PMIC device I/O interface |
| 154 | * |
| 155 | * Should be implemented by UCLASS_PMIC device drivers. The standard |
| 156 | * device operations provides the I/O interface for it's childs. |
| 157 | * |
Przemyslaw Marczak | 1031498 | 2015-05-13 13:38:26 +0200 | [diff] [blame] | 158 | * @reg_count: device's register count |
Przemyslaw Marczak | 9a8bc95 | 2015-04-20 20:07:41 +0200 | [diff] [blame] | 159 | * @read: read 'len' bytes at "reg" and store it into the 'buffer' |
| 160 | * @write: write 'len' bytes from the 'buffer' to the register at 'reg' address |
| 161 | */ |
| 162 | struct dm_pmic_ops { |
Przemyslaw Marczak | 1031498 | 2015-05-13 13:38:26 +0200 | [diff] [blame] | 163 | int (*reg_count)(struct udevice *dev); |
Przemyslaw Marczak | 9a8bc95 | 2015-04-20 20:07:41 +0200 | [diff] [blame] | 164 | int (*read)(struct udevice *dev, uint reg, uint8_t *buffer, int len); |
| 165 | int (*write)(struct udevice *dev, uint reg, const uint8_t *buffer, |
| 166 | int len); |
| 167 | }; |
| 168 | |
Przemyslaw Marczak | 1031498 | 2015-05-13 13:38:26 +0200 | [diff] [blame] | 169 | /** |
| 170 | * enum pmic_op_type - used for various pmic devices operation calls, |
Przemyslaw Marczak | 9a8bc95 | 2015-04-20 20:07:41 +0200 | [diff] [blame] | 171 | * for reduce a number of lines with the same code for read/write or get/set. |
| 172 | * |
| 173 | * @PMIC_OP_GET - get operation |
| 174 | * @PMIC_OP_SET - set operation |
| 175 | */ |
| 176 | enum pmic_op_type { |
| 177 | PMIC_OP_GET, |
| 178 | PMIC_OP_SET, |
| 179 | }; |
Łukasz Majewski | 16db062 | 2011-10-06 02:37:34 +0000 | [diff] [blame] | 180 | |
Przemyslaw Marczak | 9a8bc95 | 2015-04-20 20:07:41 +0200 | [diff] [blame] | 181 | /** |
| 182 | * struct pmic_child_info - basic device's child info for bind child nodes with |
| 183 | * the driver by the node name prefix and driver name. This is a helper struct |
Przemyslaw Marczak | 1031498 | 2015-05-13 13:38:26 +0200 | [diff] [blame] | 184 | * for function: pmic_bind_children(). |
Przemyslaw Marczak | 9a8bc95 | 2015-04-20 20:07:41 +0200 | [diff] [blame] | 185 | * |
| 186 | * @prefix - child node name prefix (or its name if is unique or single) |
| 187 | * @driver - driver name for the sub-node with prefix |
| 188 | */ |
| 189 | struct pmic_child_info { |
| 190 | const char *prefix; |
| 191 | const char *driver; |
| 192 | }; |
| 193 | |
| 194 | /* drivers/power/pmic-uclass.c */ |
| 195 | |
| 196 | /** |
Przemyslaw Marczak | 1031498 | 2015-05-13 13:38:26 +0200 | [diff] [blame] | 197 | * pmic_bind_children() - bind drivers for given parent pmic, using child info |
Przemyslaw Marczak | 9a8bc95 | 2015-04-20 20:07:41 +0200 | [diff] [blame] | 198 | * found in 'child_info' array. |
| 199 | * |
| 200 | * @pmic - pmic device - the parent of found child's |
| 201 | * @child_info - N-childs info array |
| 202 | * @return a positive number of childs, or 0 if no child found (error) |
| 203 | * |
| 204 | * Note: For N-childs the child_info array should have N+1 entries and the last |
| 205 | * entry prefix should be NULL - the same as for drivers compatible. |
| 206 | * |
| 207 | * For example, a single prefix info (N=1): |
| 208 | * static const struct pmic_child_info bind_info[] = { |
| 209 | * { .prefix = "ldo", .driver = "ldo_driver" }, |
| 210 | * { }, |
| 211 | * }; |
| 212 | * |
| 213 | * This function is useful for regulator sub-nodes: |
| 214 | * my_regulator@0xa { |
| 215 | * reg = <0xa>; |
| 216 | * (pmic - bind automatically by compatible) |
| 217 | * compatible = "my_pmic"; |
| 218 | * ... |
Przemyslaw Marczak | 1031498 | 2015-05-13 13:38:26 +0200 | [diff] [blame] | 219 | * (pmic's childs - bind by pmic_bind_children()) |
Przemyslaw Marczak | 9a8bc95 | 2015-04-20 20:07:41 +0200 | [diff] [blame] | 220 | * (nodes prefix: "ldo", driver: "my_regulator_ldo") |
| 221 | * ldo1 { ... }; |
| 222 | * ldo2 { ... }; |
| 223 | * |
| 224 | * (nodes prefix: "buck", driver: "my_regulator_buck") |
| 225 | * buck1 { ... }; |
| 226 | * buck2 { ... }; |
| 227 | * }; |
| 228 | */ |
Przemyslaw Marczak | 1031498 | 2015-05-13 13:38:26 +0200 | [diff] [blame] | 229 | int pmic_bind_children(struct udevice *pmic, int offset, |
| 230 | const struct pmic_child_info *child_info); |
Przemyslaw Marczak | 9a8bc95 | 2015-04-20 20:07:41 +0200 | [diff] [blame] | 231 | |
| 232 | /** |
| 233 | * pmic_get: get the pmic device using its name |
| 234 | * |
| 235 | * @name - device name |
| 236 | * @devp - returned pointer to the pmic device |
| 237 | * @return 0 on success or negative value of errno. |
| 238 | * |
| 239 | * The returned devp device can be used with pmic_read/write calls |
| 240 | */ |
| 241 | int pmic_get(const char *name, struct udevice **devp); |
| 242 | |
| 243 | /** |
| 244 | * pmic_reg_count: get the pmic register count |
| 245 | * |
| 246 | * The required pmic device can be obtained by 'pmic_get()' |
| 247 | * |
| 248 | * @dev - pointer to the UCLASS_PMIC device |
| 249 | * @return register count value on success or negative value of errno. |
| 250 | */ |
| 251 | int pmic_reg_count(struct udevice *dev); |
| 252 | |
| 253 | /** |
| 254 | * pmic_read/write: read/write to the UCLASS_PMIC device |
| 255 | * |
| 256 | * The required pmic device can be obtained by 'pmic_get()' |
| 257 | * |
| 258 | * @pmic - pointer to the UCLASS_PMIC device |
| 259 | * @reg - device register offset |
| 260 | * @buffer - pointer to read/write buffer |
| 261 | * @len - byte count for read/write |
| 262 | * @return 0 on success or negative value of errno. |
| 263 | */ |
| 264 | int pmic_read(struct udevice *dev, uint reg, uint8_t *buffer, int len); |
| 265 | int pmic_write(struct udevice *dev, uint reg, const uint8_t *buffer, int len); |
Simon Glass | c3f21c3 | 2015-06-23 15:39:01 -0600 | [diff] [blame] | 266 | |
| 267 | /** |
| 268 | * pmic_reg_read() - read a PMIC register value |
| 269 | * |
| 270 | * @dev: PMIC device to read |
| 271 | * @reg: Register to read |
| 272 | * @return value read on success or negative value of errno. |
| 273 | */ |
| 274 | int pmic_reg_read(struct udevice *dev, uint reg); |
| 275 | |
| 276 | /** |
| 277 | * pmic_reg_write() - write a PMIC register value |
| 278 | * |
| 279 | * @dev: PMIC device to write |
| 280 | * @reg: Register to write |
| 281 | * @value: Value to write |
| 282 | * @return 0 on success or negative value of errno. |
| 283 | */ |
| 284 | int pmic_reg_write(struct udevice *dev, uint reg, uint value); |
| 285 | |
| 286 | /** |
| 287 | * pmic_clrsetbits() - clear and set bits in a PMIC register |
| 288 | * |
| 289 | * This reads a register, optionally clears some bits, optionally sets some |
| 290 | * bits, then writes the register. |
| 291 | * |
| 292 | * @dev: PMIC device to update |
| 293 | * @reg: Register to update |
| 294 | * @clr: Bit mask to clear (set those bits that you want cleared) |
| 295 | * @set: Bit mask to set (set those bits that you want set) |
| 296 | * @return 0 on success or negative value of errno. |
| 297 | */ |
| 298 | int pmic_clrsetbits(struct udevice *dev, uint reg, uint clr, uint set); |
| 299 | |
Przemyslaw Marczak | 9a8bc95 | 2015-04-20 20:07:41 +0200 | [diff] [blame] | 300 | #endif /* CONFIG_DM_PMIC */ |
| 301 | |
| 302 | #ifdef CONFIG_POWER |
Łukasz Majewski | 1c6dba1 | 2012-11-13 03:21:55 +0000 | [diff] [blame] | 303 | int pmic_init(unsigned char bus); |
Tom Rini | 85ca252 | 2014-06-23 16:06:28 -0400 | [diff] [blame] | 304 | int power_init_board(void); |
Łukasz Majewski | 1c6dba1 | 2012-11-13 03:21:55 +0000 | [diff] [blame] | 305 | int pmic_dialog_init(unsigned char bus); |
| 306 | int check_reg(struct pmic *p, u32 reg); |
| 307 | struct pmic *pmic_alloc(void); |
| 308 | struct pmic *pmic_get(const char *s); |
Łukasz Majewski | 16db062 | 2011-10-06 02:37:34 +0000 | [diff] [blame] | 309 | int pmic_probe(struct pmic *p); |
| 310 | int pmic_reg_read(struct pmic *p, u32 reg, u32 *val); |
| 311 | int pmic_reg_write(struct pmic *p, u32 reg, u32 val); |
| 312 | int pmic_set_output(struct pmic *p, u32 reg, int ldo, int on); |
Przemyslaw Marczak | 9a8bc95 | 2015-04-20 20:07:41 +0200 | [diff] [blame] | 313 | #endif |
Łukasz Majewski | 16db062 | 2011-10-06 02:37:34 +0000 | [diff] [blame] | 314 | |
| 315 | #define pmic_i2c_addr (p->hw.i2c.addr) |
| 316 | #define pmic_i2c_tx_num (p->hw.i2c.tx_num) |
| 317 | |
| 318 | #define pmic_spi_bitlen (p->hw.spi.bitlen) |
| 319 | #define pmic_spi_flags (p->hw.spi.flags) |
| 320 | |
| 321 | #endif /* __CORE_PMIC_H_ */ |