Lines Matching +full:cros +full:- +full:ec +full:- +full:i2c
9 * Expose an I2C passthrough to the ChromeOS EC.
13 #include <linux/i2c.h>
22 * struct ec_i2c_device - Driver data for I2C tunnel
25 * @adap: I2C adapter
26 * @ec: Pointer to EC device
27 * @remote_bus: The EC bus number we tunnel to on the other side.
35 struct cros_ec_device *ec; member
44 * ec_i2c_count_message - Count bytes needed for ec_i2c_construct_message
46 * @i2c_msgs: The i2c messages to read
47 * @num: The number of i2c messages.
66 * ec_i2c_construct_message - construct a message to go to the EC
69 * a format that the EC understands.
72 * @i2c_msgs: The i2c messages to read.
73 * @num: The number of i2c messages.
89 params->port = bus_num; in ec_i2c_construct_message()
90 params->num_msgs = num; in ec_i2c_construct_message()
93 struct ec_params_i2c_passthru_msg *msg = ¶ms->msg[i]; in ec_i2c_construct_message()
95 msg->len = i2c_msg->len; in ec_i2c_construct_message()
96 msg->addr_flags = i2c_msg->addr; in ec_i2c_construct_message()
98 if (i2c_msg->flags & I2C_M_TEN) in ec_i2c_construct_message()
99 return -EINVAL; in ec_i2c_construct_message()
101 if (i2c_msg->flags & I2C_M_RD) { in ec_i2c_construct_message()
102 msg->addr_flags |= EC_I2C_FLAG_READ; in ec_i2c_construct_message()
104 memcpy(out_data, i2c_msg->buf, msg->len); in ec_i2c_construct_message()
105 out_data += msg->len; in ec_i2c_construct_message()
113 * ec_i2c_count_response - Count bytes needed for ec_i2c_parse_response
115 * @i2c_msgs: The i2c messages to to fill up.
116 * @num: The number of i2c messages expected.
134 * ec_i2c_parse_response - Parse a response from the EC
136 * We'll take the EC's response and copy it back into msgs.
139 * @i2c_msgs: The i2c messages to to fill up.
140 * @num: The number of i2c messages; will be modified to include the actual
155 if (resp->i2c_status & EC_I2C_STATUS_TIMEOUT) in ec_i2c_parse_response()
156 return -ETIMEDOUT; in ec_i2c_parse_response()
157 else if (resp->i2c_status & EC_I2C_STATUS_NAK) in ec_i2c_parse_response()
158 return -ENXIO; in ec_i2c_parse_response()
159 else if (resp->i2c_status & EC_I2C_STATUS_ERROR) in ec_i2c_parse_response()
160 return -EIO; in ec_i2c_parse_response()
163 if (resp->num_msgs > *num) in ec_i2c_parse_response()
164 return -EPROTO; in ec_i2c_parse_response()
165 *num = resp->num_msgs; in ec_i2c_parse_response()
171 memcpy(i2c_msg->buf, in_data, i2c_msg->len); in ec_i2c_parse_response()
172 in_data += i2c_msg->len; in ec_i2c_parse_response()
182 struct ec_i2c_device *bus = adap->algo_data; in ec_i2c_xfer()
183 struct device *dev = bus->dev; in ec_i2c_xfer()
184 const u16 bus_num = bus->remote_bus; in ec_i2c_xfer()
207 return -ENOMEM; in ec_i2c_xfer()
209 result = ec_i2c_construct_message(msg->data, i2c_msgs, num, bus_num); in ec_i2c_xfer()
211 dev_err(dev, "Error constructing EC i2c message %d\n", result); in ec_i2c_xfer()
215 msg->version = 0; in ec_i2c_xfer()
216 msg->command = EC_CMD_I2C_PASSTHRU; in ec_i2c_xfer()
217 msg->outsize = request_len; in ec_i2c_xfer()
218 msg->insize = response_len; in ec_i2c_xfer()
220 result = cros_ec_cmd_xfer_status(bus->ec, msg); in ec_i2c_xfer()
222 dev_err(dev, "Error transferring EC i2c message %d\n", result); in ec_i2c_xfer()
226 result = ec_i2c_parse_response(msg->data, i2c_msgs, &num); in ec_i2c_xfer()
249 struct device_node *np = pdev->dev.of_node; in ec_i2c_probe()
250 struct cros_ec_device *ec = dev_get_drvdata(pdev->dev.parent); in ec_i2c_probe() local
251 struct device *dev = &pdev->dev; in ec_i2c_probe()
256 if (!ec->cmd_xfer) { in ec_i2c_probe()
258 return -EINVAL; in ec_i2c_probe()
263 return -ENOMEM; in ec_i2c_probe()
265 err = of_property_read_u32(np, "google,remote-bus", &remote_bus); in ec_i2c_probe()
267 dev_err(dev, "Couldn't read remote-bus property\n"); in ec_i2c_probe()
270 bus->remote_bus = remote_bus; in ec_i2c_probe()
272 bus->ec = ec; in ec_i2c_probe()
273 bus->dev = dev; in ec_i2c_probe()
275 bus->adap.owner = THIS_MODULE; in ec_i2c_probe()
276 strlcpy(bus->adap.name, "cros-ec-i2c-tunnel", sizeof(bus->adap.name)); in ec_i2c_probe()
277 bus->adap.algo = &ec_i2c_algorithm; in ec_i2c_probe()
278 bus->adap.algo_data = bus; in ec_i2c_probe()
279 bus->adap.dev.parent = &pdev->dev; in ec_i2c_probe()
280 bus->adap.dev.of_node = np; in ec_i2c_probe()
281 bus->adap.retries = I2C_MAX_RETRIES; in ec_i2c_probe()
283 err = i2c_add_adapter(&bus->adap); in ec_i2c_probe()
295 i2c_del_adapter(&bus->adap); in ec_i2c_remove()
302 { .compatible = "google,cros-ec-i2c-tunnel" },
312 .name = "cros-ec-i2c-tunnel",
320 MODULE_DESCRIPTION("EC I2C tunnel driver");
321 MODULE_ALIAS("platform:cros-ec-i2c-tunnel");