xref: /OK3568_Linux_fs/kernel/drivers/i2c/busses/i2c-cros-ec-tunnel.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0+
2*4882a593Smuzhiyun // Expose an I2C passthrough to the ChromeOS EC.
3*4882a593Smuzhiyun //
4*4882a593Smuzhiyun // Copyright (C) 2013 Google, Inc.
5*4882a593Smuzhiyun 
6*4882a593Smuzhiyun #include <linux/acpi.h>
7*4882a593Smuzhiyun #include <linux/module.h>
8*4882a593Smuzhiyun #include <linux/i2c.h>
9*4882a593Smuzhiyun #include <linux/platform_data/cros_ec_commands.h>
10*4882a593Smuzhiyun #include <linux/platform_data/cros_ec_proto.h>
11*4882a593Smuzhiyun #include <linux/platform_device.h>
12*4882a593Smuzhiyun #include <linux/slab.h>
13*4882a593Smuzhiyun 
14*4882a593Smuzhiyun #define I2C_MAX_RETRIES 3
15*4882a593Smuzhiyun 
16*4882a593Smuzhiyun /**
17*4882a593Smuzhiyun  * struct ec_i2c_device - Driver data for I2C tunnel
18*4882a593Smuzhiyun  *
19*4882a593Smuzhiyun  * @dev: Device node
20*4882a593Smuzhiyun  * @adap: I2C adapter
21*4882a593Smuzhiyun  * @ec: Pointer to EC device
22*4882a593Smuzhiyun  * @remote_bus: The EC bus number we tunnel to on the other side.
23*4882a593Smuzhiyun  * @request_buf: Buffer for transmitting data; we expect most transfers to fit.
24*4882a593Smuzhiyun  * @response_buf: Buffer for receiving data; we expect most transfers to fit.
25*4882a593Smuzhiyun  */
26*4882a593Smuzhiyun 
27*4882a593Smuzhiyun struct ec_i2c_device {
28*4882a593Smuzhiyun 	struct device *dev;
29*4882a593Smuzhiyun 	struct i2c_adapter adap;
30*4882a593Smuzhiyun 	struct cros_ec_device *ec;
31*4882a593Smuzhiyun 
32*4882a593Smuzhiyun 	u16 remote_bus;
33*4882a593Smuzhiyun 
34*4882a593Smuzhiyun 	u8 request_buf[256];
35*4882a593Smuzhiyun 	u8 response_buf[256];
36*4882a593Smuzhiyun };
37*4882a593Smuzhiyun 
38*4882a593Smuzhiyun /**
39*4882a593Smuzhiyun  * ec_i2c_count_message - Count bytes needed for ec_i2c_construct_message
40*4882a593Smuzhiyun  *
41*4882a593Smuzhiyun  * @i2c_msgs: The i2c messages to read
42*4882a593Smuzhiyun  * @num: The number of i2c messages.
43*4882a593Smuzhiyun  *
44*4882a593Smuzhiyun  * Returns the number of bytes the messages will take up.
45*4882a593Smuzhiyun  */
ec_i2c_count_message(const struct i2c_msg i2c_msgs[],int num)46*4882a593Smuzhiyun static int ec_i2c_count_message(const struct i2c_msg i2c_msgs[], int num)
47*4882a593Smuzhiyun {
48*4882a593Smuzhiyun 	int i;
49*4882a593Smuzhiyun 	int size;
50*4882a593Smuzhiyun 
51*4882a593Smuzhiyun 	size = sizeof(struct ec_params_i2c_passthru);
52*4882a593Smuzhiyun 	size += num * sizeof(struct ec_params_i2c_passthru_msg);
53*4882a593Smuzhiyun 	for (i = 0; i < num; i++)
54*4882a593Smuzhiyun 		if (!(i2c_msgs[i].flags & I2C_M_RD))
55*4882a593Smuzhiyun 			size += i2c_msgs[i].len;
56*4882a593Smuzhiyun 
57*4882a593Smuzhiyun 	return size;
58*4882a593Smuzhiyun }
59*4882a593Smuzhiyun 
60*4882a593Smuzhiyun /**
61*4882a593Smuzhiyun  * ec_i2c_construct_message - construct a message to go to the EC
62*4882a593Smuzhiyun  *
63*4882a593Smuzhiyun  * This function effectively stuffs the standard i2c_msg format of Linux into
64*4882a593Smuzhiyun  * a format that the EC understands.
65*4882a593Smuzhiyun  *
66*4882a593Smuzhiyun  * @buf: The buffer to fill.  We assume that the buffer is big enough.
67*4882a593Smuzhiyun  * @i2c_msgs: The i2c messages to read.
68*4882a593Smuzhiyun  * @num: The number of i2c messages.
69*4882a593Smuzhiyun  * @bus_num: The remote bus number we want to talk to.
70*4882a593Smuzhiyun  *
71*4882a593Smuzhiyun  * Returns 0 or a negative error number.
72*4882a593Smuzhiyun  */
ec_i2c_construct_message(u8 * buf,const struct i2c_msg i2c_msgs[],int num,u16 bus_num)73*4882a593Smuzhiyun static int ec_i2c_construct_message(u8 *buf, const struct i2c_msg i2c_msgs[],
74*4882a593Smuzhiyun 				    int num, u16 bus_num)
75*4882a593Smuzhiyun {
76*4882a593Smuzhiyun 	struct ec_params_i2c_passthru *params;
77*4882a593Smuzhiyun 	u8 *out_data;
78*4882a593Smuzhiyun 	int i;
79*4882a593Smuzhiyun 
80*4882a593Smuzhiyun 	out_data = buf + sizeof(struct ec_params_i2c_passthru) +
81*4882a593Smuzhiyun 		   num * sizeof(struct ec_params_i2c_passthru_msg);
82*4882a593Smuzhiyun 
83*4882a593Smuzhiyun 	params = (struct ec_params_i2c_passthru *)buf;
84*4882a593Smuzhiyun 	params->port = bus_num;
85*4882a593Smuzhiyun 	params->num_msgs = num;
86*4882a593Smuzhiyun 	for (i = 0; i < num; i++) {
87*4882a593Smuzhiyun 		const struct i2c_msg *i2c_msg = &i2c_msgs[i];
88*4882a593Smuzhiyun 		struct ec_params_i2c_passthru_msg *msg = &params->msg[i];
89*4882a593Smuzhiyun 
90*4882a593Smuzhiyun 		msg->len = i2c_msg->len;
91*4882a593Smuzhiyun 		msg->addr_flags = i2c_msg->addr;
92*4882a593Smuzhiyun 
93*4882a593Smuzhiyun 		if (i2c_msg->flags & I2C_M_TEN)
94*4882a593Smuzhiyun 			return -EINVAL;
95*4882a593Smuzhiyun 
96*4882a593Smuzhiyun 		if (i2c_msg->flags & I2C_M_RD) {
97*4882a593Smuzhiyun 			msg->addr_flags |= EC_I2C_FLAG_READ;
98*4882a593Smuzhiyun 		} else {
99*4882a593Smuzhiyun 			memcpy(out_data, i2c_msg->buf, msg->len);
100*4882a593Smuzhiyun 			out_data += msg->len;
101*4882a593Smuzhiyun 		}
102*4882a593Smuzhiyun 	}
103*4882a593Smuzhiyun 
104*4882a593Smuzhiyun 	return 0;
105*4882a593Smuzhiyun }
106*4882a593Smuzhiyun 
107*4882a593Smuzhiyun /**
108*4882a593Smuzhiyun  * ec_i2c_count_response - Count bytes needed for ec_i2c_parse_response
109*4882a593Smuzhiyun  *
110*4882a593Smuzhiyun  * @i2c_msgs: The i2c messages to to fill up.
111*4882a593Smuzhiyun  * @num: The number of i2c messages expected.
112*4882a593Smuzhiyun  *
113*4882a593Smuzhiyun  * Returns the number of response bytes expeced.
114*4882a593Smuzhiyun  */
ec_i2c_count_response(struct i2c_msg i2c_msgs[],int num)115*4882a593Smuzhiyun static int ec_i2c_count_response(struct i2c_msg i2c_msgs[], int num)
116*4882a593Smuzhiyun {
117*4882a593Smuzhiyun 	int size;
118*4882a593Smuzhiyun 	int i;
119*4882a593Smuzhiyun 
120*4882a593Smuzhiyun 	size = sizeof(struct ec_response_i2c_passthru);
121*4882a593Smuzhiyun 	for (i = 0; i < num; i++)
122*4882a593Smuzhiyun 		if (i2c_msgs[i].flags & I2C_M_RD)
123*4882a593Smuzhiyun 			size += i2c_msgs[i].len;
124*4882a593Smuzhiyun 
125*4882a593Smuzhiyun 	return size;
126*4882a593Smuzhiyun }
127*4882a593Smuzhiyun 
128*4882a593Smuzhiyun /**
129*4882a593Smuzhiyun  * ec_i2c_parse_response - Parse a response from the EC
130*4882a593Smuzhiyun  *
131*4882a593Smuzhiyun  * We'll take the EC's response and copy it back into msgs.
132*4882a593Smuzhiyun  *
133*4882a593Smuzhiyun  * @buf: The buffer to parse.
134*4882a593Smuzhiyun  * @i2c_msgs: The i2c messages to to fill up.
135*4882a593Smuzhiyun  * @num: The number of i2c messages; will be modified to include the actual
136*4882a593Smuzhiyun  *	 number received.
137*4882a593Smuzhiyun  *
138*4882a593Smuzhiyun  * Returns 0 or a negative error number.
139*4882a593Smuzhiyun  */
ec_i2c_parse_response(const u8 * buf,struct i2c_msg i2c_msgs[],int * num)140*4882a593Smuzhiyun static int ec_i2c_parse_response(const u8 *buf, struct i2c_msg i2c_msgs[],
141*4882a593Smuzhiyun 				 int *num)
142*4882a593Smuzhiyun {
143*4882a593Smuzhiyun 	const struct ec_response_i2c_passthru *resp;
144*4882a593Smuzhiyun 	const u8 *in_data;
145*4882a593Smuzhiyun 	int i;
146*4882a593Smuzhiyun 
147*4882a593Smuzhiyun 	in_data = buf + sizeof(struct ec_response_i2c_passthru);
148*4882a593Smuzhiyun 
149*4882a593Smuzhiyun 	resp = (const struct ec_response_i2c_passthru *)buf;
150*4882a593Smuzhiyun 	if (resp->i2c_status & EC_I2C_STATUS_TIMEOUT)
151*4882a593Smuzhiyun 		return -ETIMEDOUT;
152*4882a593Smuzhiyun 	else if (resp->i2c_status & EC_I2C_STATUS_NAK)
153*4882a593Smuzhiyun 		return -ENXIO;
154*4882a593Smuzhiyun 	else if (resp->i2c_status & EC_I2C_STATUS_ERROR)
155*4882a593Smuzhiyun 		return -EIO;
156*4882a593Smuzhiyun 
157*4882a593Smuzhiyun 	/* Other side could send us back fewer messages, but not more */
158*4882a593Smuzhiyun 	if (resp->num_msgs > *num)
159*4882a593Smuzhiyun 		return -EPROTO;
160*4882a593Smuzhiyun 	*num = resp->num_msgs;
161*4882a593Smuzhiyun 
162*4882a593Smuzhiyun 	for (i = 0; i < *num; i++) {
163*4882a593Smuzhiyun 		struct i2c_msg *i2c_msg = &i2c_msgs[i];
164*4882a593Smuzhiyun 
165*4882a593Smuzhiyun 		if (i2c_msgs[i].flags & I2C_M_RD) {
166*4882a593Smuzhiyun 			memcpy(i2c_msg->buf, in_data, i2c_msg->len);
167*4882a593Smuzhiyun 			in_data += i2c_msg->len;
168*4882a593Smuzhiyun 		}
169*4882a593Smuzhiyun 	}
170*4882a593Smuzhiyun 
171*4882a593Smuzhiyun 	return 0;
172*4882a593Smuzhiyun }
173*4882a593Smuzhiyun 
ec_i2c_xfer(struct i2c_adapter * adap,struct i2c_msg i2c_msgs[],int num)174*4882a593Smuzhiyun static int ec_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg i2c_msgs[],
175*4882a593Smuzhiyun 		       int num)
176*4882a593Smuzhiyun {
177*4882a593Smuzhiyun 	struct ec_i2c_device *bus = adap->algo_data;
178*4882a593Smuzhiyun 	struct device *dev = bus->dev;
179*4882a593Smuzhiyun 	const u16 bus_num = bus->remote_bus;
180*4882a593Smuzhiyun 	int request_len;
181*4882a593Smuzhiyun 	int response_len;
182*4882a593Smuzhiyun 	int alloc_size;
183*4882a593Smuzhiyun 	int result;
184*4882a593Smuzhiyun 	struct cros_ec_command *msg;
185*4882a593Smuzhiyun 
186*4882a593Smuzhiyun 	request_len = ec_i2c_count_message(i2c_msgs, num);
187*4882a593Smuzhiyun 	if (request_len < 0) {
188*4882a593Smuzhiyun 		dev_warn(dev, "Error constructing message %d\n", request_len);
189*4882a593Smuzhiyun 		return request_len;
190*4882a593Smuzhiyun 	}
191*4882a593Smuzhiyun 
192*4882a593Smuzhiyun 	response_len = ec_i2c_count_response(i2c_msgs, num);
193*4882a593Smuzhiyun 	if (response_len < 0) {
194*4882a593Smuzhiyun 		/* Unexpected; no errors should come when NULL response */
195*4882a593Smuzhiyun 		dev_warn(dev, "Error preparing response %d\n", response_len);
196*4882a593Smuzhiyun 		return response_len;
197*4882a593Smuzhiyun 	}
198*4882a593Smuzhiyun 
199*4882a593Smuzhiyun 	alloc_size = max(request_len, response_len);
200*4882a593Smuzhiyun 	msg = kmalloc(sizeof(*msg) + alloc_size, GFP_KERNEL);
201*4882a593Smuzhiyun 	if (!msg)
202*4882a593Smuzhiyun 		return -ENOMEM;
203*4882a593Smuzhiyun 
204*4882a593Smuzhiyun 	result = ec_i2c_construct_message(msg->data, i2c_msgs, num, bus_num);
205*4882a593Smuzhiyun 	if (result) {
206*4882a593Smuzhiyun 		dev_err(dev, "Error constructing EC i2c message %d\n", result);
207*4882a593Smuzhiyun 		goto exit;
208*4882a593Smuzhiyun 	}
209*4882a593Smuzhiyun 
210*4882a593Smuzhiyun 	msg->version = 0;
211*4882a593Smuzhiyun 	msg->command = EC_CMD_I2C_PASSTHRU;
212*4882a593Smuzhiyun 	msg->outsize = request_len;
213*4882a593Smuzhiyun 	msg->insize = response_len;
214*4882a593Smuzhiyun 
215*4882a593Smuzhiyun 	result = cros_ec_cmd_xfer_status(bus->ec, msg);
216*4882a593Smuzhiyun 	if (result < 0) {
217*4882a593Smuzhiyun 		dev_err(dev, "Error transferring EC i2c message %d\n", result);
218*4882a593Smuzhiyun 		goto exit;
219*4882a593Smuzhiyun 	}
220*4882a593Smuzhiyun 
221*4882a593Smuzhiyun 	result = ec_i2c_parse_response(msg->data, i2c_msgs, &num);
222*4882a593Smuzhiyun 	if (result < 0)
223*4882a593Smuzhiyun 		goto exit;
224*4882a593Smuzhiyun 
225*4882a593Smuzhiyun 	/* Indicate success by saying how many messages were sent */
226*4882a593Smuzhiyun 	result = num;
227*4882a593Smuzhiyun exit:
228*4882a593Smuzhiyun 	kfree(msg);
229*4882a593Smuzhiyun 	return result;
230*4882a593Smuzhiyun }
231*4882a593Smuzhiyun 
ec_i2c_functionality(struct i2c_adapter * adap)232*4882a593Smuzhiyun static u32 ec_i2c_functionality(struct i2c_adapter *adap)
233*4882a593Smuzhiyun {
234*4882a593Smuzhiyun 	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
235*4882a593Smuzhiyun }
236*4882a593Smuzhiyun 
237*4882a593Smuzhiyun static const struct i2c_algorithm ec_i2c_algorithm = {
238*4882a593Smuzhiyun 	.master_xfer	= ec_i2c_xfer,
239*4882a593Smuzhiyun 	.functionality	= ec_i2c_functionality,
240*4882a593Smuzhiyun };
241*4882a593Smuzhiyun 
ec_i2c_probe(struct platform_device * pdev)242*4882a593Smuzhiyun static int ec_i2c_probe(struct platform_device *pdev)
243*4882a593Smuzhiyun {
244*4882a593Smuzhiyun 	struct cros_ec_device *ec = dev_get_drvdata(pdev->dev.parent);
245*4882a593Smuzhiyun 	struct device *dev = &pdev->dev;
246*4882a593Smuzhiyun 	struct ec_i2c_device *bus = NULL;
247*4882a593Smuzhiyun 	u32 remote_bus;
248*4882a593Smuzhiyun 	int err;
249*4882a593Smuzhiyun 
250*4882a593Smuzhiyun 	if (!ec->cmd_xfer) {
251*4882a593Smuzhiyun 		dev_err(dev, "Missing sendrecv\n");
252*4882a593Smuzhiyun 		return -EINVAL;
253*4882a593Smuzhiyun 	}
254*4882a593Smuzhiyun 
255*4882a593Smuzhiyun 	bus = devm_kzalloc(dev, sizeof(*bus), GFP_KERNEL);
256*4882a593Smuzhiyun 	if (bus == NULL)
257*4882a593Smuzhiyun 		return -ENOMEM;
258*4882a593Smuzhiyun 
259*4882a593Smuzhiyun 	err = device_property_read_u32(dev, "google,remote-bus", &remote_bus);
260*4882a593Smuzhiyun 	if (err) {
261*4882a593Smuzhiyun 		dev_err(dev, "Couldn't read remote-bus property\n");
262*4882a593Smuzhiyun 		return err;
263*4882a593Smuzhiyun 	}
264*4882a593Smuzhiyun 	bus->remote_bus = remote_bus;
265*4882a593Smuzhiyun 
266*4882a593Smuzhiyun 	bus->ec = ec;
267*4882a593Smuzhiyun 	bus->dev = dev;
268*4882a593Smuzhiyun 
269*4882a593Smuzhiyun 	bus->adap.owner = THIS_MODULE;
270*4882a593Smuzhiyun 	strlcpy(bus->adap.name, "cros-ec-i2c-tunnel", sizeof(bus->adap.name));
271*4882a593Smuzhiyun 	bus->adap.algo = &ec_i2c_algorithm;
272*4882a593Smuzhiyun 	bus->adap.algo_data = bus;
273*4882a593Smuzhiyun 	bus->adap.dev.parent = &pdev->dev;
274*4882a593Smuzhiyun 	bus->adap.dev.of_node = pdev->dev.of_node;
275*4882a593Smuzhiyun 	bus->adap.retries = I2C_MAX_RETRIES;
276*4882a593Smuzhiyun 	ACPI_COMPANION_SET(&bus->adap.dev, ACPI_COMPANION(&pdev->dev));
277*4882a593Smuzhiyun 
278*4882a593Smuzhiyun 	err = i2c_add_adapter(&bus->adap);
279*4882a593Smuzhiyun 	if (err)
280*4882a593Smuzhiyun 		return err;
281*4882a593Smuzhiyun 	platform_set_drvdata(pdev, bus);
282*4882a593Smuzhiyun 
283*4882a593Smuzhiyun 	return err;
284*4882a593Smuzhiyun }
285*4882a593Smuzhiyun 
ec_i2c_remove(struct platform_device * dev)286*4882a593Smuzhiyun static int ec_i2c_remove(struct platform_device *dev)
287*4882a593Smuzhiyun {
288*4882a593Smuzhiyun 	struct ec_i2c_device *bus = platform_get_drvdata(dev);
289*4882a593Smuzhiyun 
290*4882a593Smuzhiyun 	i2c_del_adapter(&bus->adap);
291*4882a593Smuzhiyun 
292*4882a593Smuzhiyun 	return 0;
293*4882a593Smuzhiyun }
294*4882a593Smuzhiyun 
295*4882a593Smuzhiyun static const struct of_device_id cros_ec_i2c_of_match[] = {
296*4882a593Smuzhiyun 	{ .compatible = "google,cros-ec-i2c-tunnel" },
297*4882a593Smuzhiyun 	{},
298*4882a593Smuzhiyun };
299*4882a593Smuzhiyun MODULE_DEVICE_TABLE(of, cros_ec_i2c_of_match);
300*4882a593Smuzhiyun 
301*4882a593Smuzhiyun static const struct acpi_device_id cros_ec_i2c_tunnel_acpi_id[] = {
302*4882a593Smuzhiyun 	{ "GOOG0012", 0 },
303*4882a593Smuzhiyun 	{ }
304*4882a593Smuzhiyun };
305*4882a593Smuzhiyun MODULE_DEVICE_TABLE(acpi, cros_ec_i2c_tunnel_acpi_id);
306*4882a593Smuzhiyun 
307*4882a593Smuzhiyun static struct platform_driver ec_i2c_tunnel_driver = {
308*4882a593Smuzhiyun 	.probe = ec_i2c_probe,
309*4882a593Smuzhiyun 	.remove = ec_i2c_remove,
310*4882a593Smuzhiyun 	.driver = {
311*4882a593Smuzhiyun 		.name = "cros-ec-i2c-tunnel",
312*4882a593Smuzhiyun 		.acpi_match_table = ACPI_PTR(cros_ec_i2c_tunnel_acpi_id),
313*4882a593Smuzhiyun 		.of_match_table = of_match_ptr(cros_ec_i2c_of_match),
314*4882a593Smuzhiyun 	},
315*4882a593Smuzhiyun };
316*4882a593Smuzhiyun 
317*4882a593Smuzhiyun module_platform_driver(ec_i2c_tunnel_driver);
318*4882a593Smuzhiyun 
319*4882a593Smuzhiyun MODULE_LICENSE("GPL");
320*4882a593Smuzhiyun MODULE_DESCRIPTION("EC I2C tunnel driver");
321*4882a593Smuzhiyun MODULE_ALIAS("platform:cros-ec-i2c-tunnel");
322