]>
Commit | Line | Data |
---|---|---|
83d290c5 | 1 | // SPDX-License-Identifier: GPL-2.0+ |
e542b7f0 ŁM |
2 | /* |
3 | * Copyright (C) 2011 Samsung Electronics | |
4 | * Lukasz Majewski <[email protected]> | |
5 | * | |
6 | * (C) Copyright 2010 | |
7 | * Stefano Babic, DENX Software Engineering, [email protected] | |
8 | * | |
9 | * (C) Copyright 2008-2009 Freescale Semiconductor, Inc. | |
bb1165f9 | 10 | * (C) Copyright 2019 NXP |
e542b7f0 ŁM |
11 | */ |
12 | ||
13 | #include <common.h> | |
f7ae49fc | 14 | #include <log.h> |
e542b7f0 | 15 | #include <linux/types.h> |
c7336815 | 16 | #include <power/pmic.h> |
e542b7f0 | 17 | #include <i2c.h> |
afc366f0 | 18 | #include <linux/compiler.h> |
e542b7f0 ŁM |
19 | |
20 | int pmic_reg_write(struct pmic *p, u32 reg, u32 val) | |
21 | { | |
22 | unsigned char buf[4] = { 0 }; | |
23 | ||
c7336815 | 24 | if (check_reg(p, reg)) |
505cf475 | 25 | return -EINVAL; |
bb1165f9 BL |
26 | #if defined(CONFIG_DM_I2C) |
27 | struct udevice *dev; | |
28 | int ret; | |
e542b7f0 | 29 | |
bb1165f9 BL |
30 | ret = i2c_get_chip_for_busnum(p->bus, pmic_i2c_addr, |
31 | 1, &dev); | |
32 | if (ret) { | |
33 | printf("%s: Cannot find udev for a bus %d\n", __func__, | |
34 | p->bus); | |
35 | return -ENXIO; | |
36 | } | |
37 | #else /* Non DM I2C support - will be removed */ | |
0b259dc2 | 38 | I2C_SET_BUS(p->bus); |
bb1165f9 | 39 | #endif |
0b259dc2 | 40 | |
e542b7f0 ŁM |
41 | switch (pmic_i2c_tx_num) { |
42 | case 3: | |
86879d71 ŁM |
43 | if (p->sensor_byte_order == PMIC_SENSOR_BYTE_ORDER_BIG) { |
44 | buf[2] = (cpu_to_le32(val) >> 16) & 0xff; | |
45 | buf[1] = (cpu_to_le32(val) >> 8) & 0xff; | |
46 | buf[0] = cpu_to_le32(val) & 0xff; | |
47 | } else { | |
48 | buf[0] = (cpu_to_le32(val) >> 16) & 0xff; | |
49 | buf[1] = (cpu_to_le32(val) >> 8) & 0xff; | |
50 | buf[2] = cpu_to_le32(val) & 0xff; | |
51 | } | |
e542b7f0 | 52 | break; |
b5bf9caf | 53 | case 2: |
86879d71 ŁM |
54 | if (p->sensor_byte_order == PMIC_SENSOR_BYTE_ORDER_BIG) { |
55 | buf[1] = (cpu_to_le32(val) >> 8) & 0xff; | |
56 | buf[0] = cpu_to_le32(val) & 0xff; | |
57 | } else { | |
58 | buf[0] = (cpu_to_le32(val) >> 8) & 0xff; | |
59 | buf[1] = cpu_to_le32(val) & 0xff; | |
60 | } | |
b5bf9caf | 61 | break; |
e542b7f0 | 62 | case 1: |
86879d71 | 63 | buf[0] = cpu_to_le32(val) & 0xff; |
e542b7f0 | 64 | break; |
a22429d2 FE |
65 | default: |
66 | printf("%s: invalid tx_num: %d", __func__, pmic_i2c_tx_num); | |
505cf475 | 67 | return -EINVAL; |
e542b7f0 ŁM |
68 | } |
69 | ||
bb1165f9 BL |
70 | #if defined(CONFIG_DM_I2C) |
71 | return dm_i2c_write(dev, reg, buf, pmic_i2c_tx_num); | |
72 | #else | |
505cf475 | 73 | return i2c_write(pmic_i2c_addr, reg, 1, buf, pmic_i2c_tx_num); |
bb1165f9 | 74 | #endif |
e542b7f0 ŁM |
75 | } |
76 | ||
77 | int pmic_reg_read(struct pmic *p, u32 reg, u32 *val) | |
78 | { | |
79 | unsigned char buf[4] = { 0 }; | |
80 | u32 ret_val = 0; | |
505cf475 | 81 | int ret; |
e542b7f0 | 82 | |
c7336815 | 83 | if (check_reg(p, reg)) |
505cf475 | 84 | return -EINVAL; |
e542b7f0 | 85 | |
bb1165f9 BL |
86 | #if defined(CONFIG_DM_I2C) |
87 | struct udevice *dev; | |
0b259dc2 | 88 | |
bb1165f9 BL |
89 | ret = i2c_get_chip_for_busnum(p->bus, pmic_i2c_addr, |
90 | 1, &dev); | |
91 | if (ret) { | |
92 | printf("%s: Cannot find udev for a bus %d\n", __func__, | |
93 | p->bus); | |
94 | return -ENXIO; | |
95 | } | |
96 | ret = dm_i2c_read(dev, reg, buf, pmic_i2c_tx_num); | |
97 | #else /* Non DM I2C support - will be removed */ | |
98 | I2C_SET_BUS(p->bus); | |
505cf475 | 99 | ret = i2c_read(pmic_i2c_addr, reg, 1, buf, pmic_i2c_tx_num); |
bb1165f9 | 100 | #endif |
505cf475 JC |
101 | if (ret) |
102 | return ret; | |
e542b7f0 ŁM |
103 | |
104 | switch (pmic_i2c_tx_num) { | |
105 | case 3: | |
86879d71 ŁM |
106 | if (p->sensor_byte_order == PMIC_SENSOR_BYTE_ORDER_BIG) |
107 | ret_val = le32_to_cpu(buf[2] << 16 | |
108 | | buf[1] << 8 | buf[0]); | |
109 | else | |
110 | ret_val = le32_to_cpu(buf[0] << 16 | | |
111 | buf[1] << 8 | buf[2]); | |
e542b7f0 | 112 | break; |
b5bf9caf | 113 | case 2: |
86879d71 ŁM |
114 | if (p->sensor_byte_order == PMIC_SENSOR_BYTE_ORDER_BIG) |
115 | ret_val = le32_to_cpu(buf[1] << 8 | buf[0]); | |
116 | else | |
117 | ret_val = le32_to_cpu(buf[0] << 8 | buf[1]); | |
b5bf9caf | 118 | break; |
e542b7f0 | 119 | case 1: |
86879d71 | 120 | ret_val = le32_to_cpu(buf[0]); |
e542b7f0 | 121 | break; |
a22429d2 FE |
122 | default: |
123 | printf("%s: invalid tx_num: %d", __func__, pmic_i2c_tx_num); | |
505cf475 | 124 | return -EINVAL; |
e542b7f0 ŁM |
125 | } |
126 | memcpy(val, &ret_val, sizeof(ret_val)); | |
127 | ||
128 | return 0; | |
129 | } | |
130 | ||
131 | int pmic_probe(struct pmic *p) | |
132 | { | |
b5bf9caf | 133 | debug("Bus: %d PMIC:%s probed!\n", p->bus, p->name); |
bb1165f9 BL |
134 | #if defined(CONFIG_DM_I2C) |
135 | struct udevice *dev; | |
136 | int ret; | |
137 | ||
138 | ret = i2c_get_chip_for_busnum(p->bus, pmic_i2c_addr, | |
139 | 1, &dev); | |
140 | if (ret) { | |
141 | printf("%s: Cannot find udev for a bus %d\n", __func__, | |
142 | p->bus); | |
143 | return -ENXIO; | |
144 | } | |
145 | #else /* Non DM I2C support - will be removed */ | |
146 | i2c_set_bus_num(p->bus); | |
e542b7f0 ŁM |
147 | if (i2c_probe(pmic_i2c_addr)) { |
148 | printf("Can't find PMIC:%s\n", p->name); | |
505cf475 | 149 | return -ENODEV; |
e542b7f0 | 150 | } |
bb1165f9 | 151 | #endif |
e542b7f0 ŁM |
152 | |
153 | return 0; | |
154 | } |