1 // SPDX-License-Identifier: GPL-2.0
3 * I2C access driver for TI TPS65224/TPS6594/TPS6593/LP8764 PMICs
5 * Copyright (C) 2023 BayLibre Incorporated - https://www.baylibre.com/
8 #include <linux/crc8.h>
10 #include <linux/module.h>
11 #include <linux/mod_devicetable.h>
12 #include <linux/of_device.h>
13 #include <linux/regmap.h>
15 #include <linux/mfd/tps6594.h>
17 static bool enable_crc
;
18 module_param(enable_crc
, bool, 0444);
19 MODULE_PARM_DESC(enable_crc
, "Enable CRC feature for I2C interface");
21 DECLARE_CRC8_TABLE(tps6594_i2c_crc_table
);
23 static int tps6594_i2c_transfer(struct i2c_adapter
*adap
, struct i2c_msg
*msgs
, int num
)
25 int ret
= i2c_transfer(adap
, msgs
, num
);
35 static int tps6594_i2c_reg_read_with_crc(struct i2c_client
*client
, u8 page
, u8 reg
, u8
*val
)
37 struct i2c_msg msgs
[2];
38 u8 buf_rx
[] = { 0, 0 };
39 /* I2C address = I2C base address + Page index */
40 const u8 addr
= client
->addr
+ page
;
42 * CRC is calculated from every bit included in the protocol
43 * except the ACK bits from the target. Byte stream is:
44 * - B0: (I2C_addr_7bits << 1) | WR_bit, with WR_bit = 0
46 * - B2: (I2C_addr_7bits << 1) | RD_bit, with RD_bit = 1
48 * - B4: CRC from B0-B1-B2-B3
50 u8 crc_data
[] = { addr
<< 1, reg
, addr
<< 1 | 1, 0 };
59 /* Read data and CRC */
60 msgs
[1].addr
= msgs
[0].addr
;
61 msgs
[1].flags
= I2C_M_RD
;
65 ret
= tps6594_i2c_transfer(client
->adapter
, msgs
, 2);
69 crc_data
[sizeof(crc_data
) - 1] = *val
= buf_rx
[0];
70 if (buf_rx
[1] != crc8(tps6594_i2c_crc_table
, crc_data
, sizeof(crc_data
), CRC8_INIT_VALUE
))
76 static int tps6594_i2c_reg_write_with_crc(struct i2c_client
*client
, u8 page
, u8 reg
, u8 val
)
79 u8 buf
[] = { reg
, val
, 0 };
80 /* I2C address = I2C base address + Page index */
81 const u8 addr
= client
->addr
+ page
;
83 * CRC is calculated from every bit included in the protocol
84 * except the ACK bits from the target. Byte stream is:
85 * - B0: (I2C_addr_7bits << 1) | WR_bit, with WR_bit = 0
88 * - B3: CRC from B0-B1-B2
90 const u8 crc_data
[] = { addr
<< 1, reg
, val
};
92 /* Write register, data and CRC */
94 msg
.flags
= client
->flags
& I2C_M_TEN
;
95 msg
.len
= sizeof(buf
);
98 buf
[msg
.len
- 1] = crc8(tps6594_i2c_crc_table
, crc_data
, sizeof(crc_data
), CRC8_INIT_VALUE
);
100 return tps6594_i2c_transfer(client
->adapter
, &msg
, 1);
103 static int tps6594_i2c_read(void *context
, const void *reg_buf
, size_t reg_size
,
104 void *val_buf
, size_t val_size
)
106 struct i2c_client
*client
= context
;
107 struct tps6594
*tps
= i2c_get_clientdata(client
);
108 struct i2c_msg msgs
[2];
109 const u8
*reg_bytes
= reg_buf
;
110 u8
*val_bytes
= val_buf
;
111 const u8 page
= reg_bytes
[1];
112 u8 reg
= reg_bytes
[0];
118 * Auto-increment feature does not support CRC protocol.
119 * Converts the bulk read operation into a series of single read operations.
121 for (i
= 0 ; ret
== 0 && i
< val_size
; i
++)
122 ret
= tps6594_i2c_reg_read_with_crc(client
, page
, reg
+ i
, val_bytes
+ i
);
127 /* Write register: I2C address = I2C base address + Page index */
128 msgs
[0].addr
= client
->addr
+ page
;
134 msgs
[1].addr
= msgs
[0].addr
;
135 msgs
[1].flags
= I2C_M_RD
;
136 msgs
[1].len
= val_size
;
137 msgs
[1].buf
= val_bytes
;
139 return tps6594_i2c_transfer(client
->adapter
, msgs
, 2);
142 static int tps6594_i2c_write(void *context
, const void *data
, size_t count
)
144 struct i2c_client
*client
= context
;
145 struct tps6594
*tps
= i2c_get_clientdata(client
);
147 const u8
*bytes
= data
;
149 const u8 page
= bytes
[1];
150 const u8 reg
= bytes
[0];
156 * Auto-increment feature does not support CRC protocol.
157 * Converts the bulk write operation into a series of single write operations.
159 for (i
= 0 ; ret
== 0 && i
< count
- 2 ; i
++)
160 ret
= tps6594_i2c_reg_write_with_crc(client
, page
, reg
+ i
, bytes
[i
+ 2]);
165 /* Setup buffer: page byte is not sent */
166 buf
= kzalloc(--count
, GFP_KERNEL
);
171 for (i
= 0 ; i
< count
- 1 ; i
++)
172 buf
[i
+ 1] = bytes
[i
+ 2];
174 /* Write register and data: I2C address = I2C base address + Page index */
175 msg
.addr
= client
->addr
+ page
;
176 msg
.flags
= client
->flags
& I2C_M_TEN
;
180 ret
= tps6594_i2c_transfer(client
->adapter
, &msg
, 1);
186 static struct regmap_config tps6594_i2c_regmap_config
= {
189 .max_register
= TPS6594_REG_DWD_FAIL_CNT_REG
,
190 .volatile_table
= &tps6594_volatile_table
,
191 .read
= tps6594_i2c_read
,
192 .write
= tps6594_i2c_write
,
195 static const struct of_device_id tps6594_i2c_of_match_table
[] = {
196 { .compatible
= "ti,tps6594-q1", .data
= (void *)TPS6594
, },
197 { .compatible
= "ti,tps6593-q1", .data
= (void *)TPS6593
, },
198 { .compatible
= "ti,lp8764-q1", .data
= (void *)LP8764
, },
199 { .compatible
= "ti,tps65224-q1", .data
= (void *)TPS65224
, },
202 MODULE_DEVICE_TABLE(of
, tps6594_i2c_of_match_table
);
204 static int tps6594_i2c_probe(struct i2c_client
*client
)
206 struct device
*dev
= &client
->dev
;
208 const struct of_device_id
*match
;
210 tps
= devm_kzalloc(dev
, sizeof(*tps
), GFP_KERNEL
);
214 i2c_set_clientdata(client
, tps
);
217 tps
->reg
= client
->addr
;
218 tps
->irq
= client
->irq
;
220 match
= of_match_device(tps6594_i2c_of_match_table
, dev
);
222 return dev_err_probe(dev
, -EINVAL
, "Failed to find matching chip ID\n");
223 tps
->chip_id
= (unsigned long)match
->data
;
225 if (tps
->chip_id
== TPS65224
)
226 tps6594_i2c_regmap_config
.volatile_table
= &tps65224_volatile_table
;
228 tps
->regmap
= devm_regmap_init(dev
, NULL
, client
, &tps6594_i2c_regmap_config
);
229 if (IS_ERR(tps
->regmap
))
230 return dev_err_probe(dev
, PTR_ERR(tps
->regmap
), "Failed to init regmap\n");
232 crc8_populate_msb(tps6594_i2c_crc_table
, TPS6594_CRC8_POLYNOMIAL
);
234 return tps6594_device_init(tps
, enable_crc
);
237 static struct i2c_driver tps6594_i2c_driver
= {
240 .of_match_table
= tps6594_i2c_of_match_table
,
242 .probe
= tps6594_i2c_probe
,
244 module_i2c_driver(tps6594_i2c_driver
);
246 MODULE_AUTHOR("Julien Panis <jpanis@baylibre.com>");
247 MODULE_DESCRIPTION("I2C Interface Driver for TPS65224, TPS6594/3, and LP8764");
248 MODULE_LICENSE("GPL");