Merge tag 'drm-misc-fixes-2018-11-21' of git://anongit.freedesktop.org/drm/drm-misc...
[sfrench/cifs-2.6.git] / drivers / usb / typec / ucsi / ucsi_ccg.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * UCSI driver for Cypress CCGx Type-C controller
4  *
5  * Copyright (C) 2017-2018 NVIDIA Corporation. All rights reserved.
6  * Author: Ajay Gupta <ajayg@nvidia.com>
7  *
8  * Some code borrowed from drivers/usb/typec/ucsi/ucsi_acpi.c
9  */
10 #include <linux/acpi.h>
11 #include <linux/delay.h>
12 #include <linux/i2c.h>
13 #include <linux/module.h>
14 #include <linux/pci.h>
15 #include <linux/platform_device.h>
16
17 #include <asm/unaligned.h>
18 #include "ucsi.h"
19
20 struct ucsi_ccg {
21         struct device *dev;
22         struct ucsi *ucsi;
23         struct ucsi_ppm ppm;
24         struct i2c_client *client;
25 };
26
27 #define CCGX_RAB_INTR_REG                       0x06
28 #define CCGX_RAB_UCSI_CONTROL                   0x39
29 #define CCGX_RAB_UCSI_CONTROL_START             BIT(0)
30 #define CCGX_RAB_UCSI_CONTROL_STOP              BIT(1)
31 #define CCGX_RAB_UCSI_DATA_BLOCK(offset)        (0xf000 | ((offset) & 0xff))
32
33 static int ccg_read(struct ucsi_ccg *uc, u16 rab, u8 *data, u32 len)
34 {
35         struct i2c_client *client = uc->client;
36         const struct i2c_adapter_quirks *quirks = client->adapter->quirks;
37         unsigned char buf[2];
38         struct i2c_msg msgs[] = {
39                 {
40                         .addr   = client->addr,
41                         .flags  = 0x0,
42                         .len    = sizeof(buf),
43                         .buf    = buf,
44                 },
45                 {
46                         .addr   = client->addr,
47                         .flags  = I2C_M_RD,
48                         .buf    = data,
49                 },
50         };
51         u32 rlen, rem_len = len, max_read_len = len;
52         int status;
53
54         /* check any max_read_len limitation on i2c adapter */
55         if (quirks && quirks->max_read_len)
56                 max_read_len = quirks->max_read_len;
57
58         while (rem_len > 0) {
59                 msgs[1].buf = &data[len - rem_len];
60                 rlen = min_t(u16, rem_len, max_read_len);
61                 msgs[1].len = rlen;
62                 put_unaligned_le16(rab, buf);
63                 status = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
64                 if (status < 0) {
65                         dev_err(uc->dev, "i2c_transfer failed %d\n", status);
66                         return status;
67                 }
68                 rab += rlen;
69                 rem_len -= rlen;
70         }
71
72         return 0;
73 }
74
75 static int ccg_write(struct ucsi_ccg *uc, u16 rab, u8 *data, u32 len)
76 {
77         struct i2c_client *client = uc->client;
78         unsigned char *buf;
79         struct i2c_msg msgs[] = {
80                 {
81                         .addr   = client->addr,
82                         .flags  = 0x0,
83                 }
84         };
85         int status;
86
87         buf = kzalloc(len + sizeof(rab), GFP_KERNEL);
88         if (!buf)
89                 return -ENOMEM;
90
91         put_unaligned_le16(rab, buf);
92         memcpy(buf + sizeof(rab), data, len);
93
94         msgs[0].len = len + sizeof(rab);
95         msgs[0].buf = buf;
96
97         status = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
98         if (status < 0) {
99                 dev_err(uc->dev, "i2c_transfer failed %d\n", status);
100                 kfree(buf);
101                 return status;
102         }
103
104         kfree(buf);
105         return 0;
106 }
107
108 static int ucsi_ccg_init(struct ucsi_ccg *uc)
109 {
110         unsigned int count = 10;
111         u8 data;
112         int status;
113
114         data = CCGX_RAB_UCSI_CONTROL_STOP;
115         status = ccg_write(uc, CCGX_RAB_UCSI_CONTROL, &data, sizeof(data));
116         if (status < 0)
117                 return status;
118
119         data = CCGX_RAB_UCSI_CONTROL_START;
120         status = ccg_write(uc, CCGX_RAB_UCSI_CONTROL, &data, sizeof(data));
121         if (status < 0)
122                 return status;
123
124         /*
125          * Flush CCGx RESPONSE queue by acking interrupts. Above ucsi control
126          * register write will push response which must be cleared.
127          */
128         do {
129                 status = ccg_read(uc, CCGX_RAB_INTR_REG, &data, sizeof(data));
130                 if (status < 0)
131                         return status;
132
133                 if (!data)
134                         return 0;
135
136                 status = ccg_write(uc, CCGX_RAB_INTR_REG, &data, sizeof(data));
137                 if (status < 0)
138                         return status;
139
140                 usleep_range(10000, 11000);
141         } while (--count);
142
143         return -ETIMEDOUT;
144 }
145
146 static int ucsi_ccg_send_data(struct ucsi_ccg *uc)
147 {
148         u8 *ppm = (u8 *)uc->ppm.data;
149         int status;
150         u16 rab;
151
152         rab = CCGX_RAB_UCSI_DATA_BLOCK(offsetof(struct ucsi_data, message_out));
153         status = ccg_write(uc, rab, ppm +
154                            offsetof(struct ucsi_data, message_out),
155                            sizeof(uc->ppm.data->message_out));
156         if (status < 0)
157                 return status;
158
159         rab = CCGX_RAB_UCSI_DATA_BLOCK(offsetof(struct ucsi_data, ctrl));
160         return ccg_write(uc, rab, ppm + offsetof(struct ucsi_data, ctrl),
161                          sizeof(uc->ppm.data->ctrl));
162 }
163
164 static int ucsi_ccg_recv_data(struct ucsi_ccg *uc)
165 {
166         u8 *ppm = (u8 *)uc->ppm.data;
167         int status;
168         u16 rab;
169
170         rab = CCGX_RAB_UCSI_DATA_BLOCK(offsetof(struct ucsi_data, cci));
171         status = ccg_read(uc, rab, ppm + offsetof(struct ucsi_data, cci),
172                           sizeof(uc->ppm.data->cci));
173         if (status < 0)
174                 return status;
175
176         rab = CCGX_RAB_UCSI_DATA_BLOCK(offsetof(struct ucsi_data, message_in));
177         return ccg_read(uc, rab, ppm + offsetof(struct ucsi_data, message_in),
178                         sizeof(uc->ppm.data->message_in));
179 }
180
181 static int ucsi_ccg_ack_interrupt(struct ucsi_ccg *uc)
182 {
183         int status;
184         unsigned char data;
185
186         status = ccg_read(uc, CCGX_RAB_INTR_REG, &data, sizeof(data));
187         if (status < 0)
188                 return status;
189
190         return ccg_write(uc, CCGX_RAB_INTR_REG, &data, sizeof(data));
191 }
192
193 static int ucsi_ccg_sync(struct ucsi_ppm *ppm)
194 {
195         struct ucsi_ccg *uc = container_of(ppm, struct ucsi_ccg, ppm);
196         int status;
197
198         status = ucsi_ccg_recv_data(uc);
199         if (status < 0)
200                 return status;
201
202         /* ack interrupt to allow next command to run */
203         return ucsi_ccg_ack_interrupt(uc);
204 }
205
206 static int ucsi_ccg_cmd(struct ucsi_ppm *ppm, struct ucsi_control *ctrl)
207 {
208         struct ucsi_ccg *uc = container_of(ppm, struct ucsi_ccg, ppm);
209
210         ppm->data->ctrl.raw_cmd = ctrl->raw_cmd;
211         return ucsi_ccg_send_data(uc);
212 }
213
214 static irqreturn_t ccg_irq_handler(int irq, void *data)
215 {
216         struct ucsi_ccg *uc = data;
217
218         ucsi_notify(uc->ucsi);
219
220         return IRQ_HANDLED;
221 }
222
223 static int ucsi_ccg_probe(struct i2c_client *client,
224                           const struct i2c_device_id *id)
225 {
226         struct device *dev = &client->dev;
227         struct ucsi_ccg *uc;
228         int status;
229         u16 rab;
230
231         uc = devm_kzalloc(dev, sizeof(*uc), GFP_KERNEL);
232         if (!uc)
233                 return -ENOMEM;
234
235         uc->ppm.data = devm_kzalloc(dev, sizeof(struct ucsi_data), GFP_KERNEL);
236         if (!uc->ppm.data)
237                 return -ENOMEM;
238
239         uc->ppm.cmd = ucsi_ccg_cmd;
240         uc->ppm.sync = ucsi_ccg_sync;
241         uc->dev = dev;
242         uc->client = client;
243
244         /* reset ccg device and initialize ucsi */
245         status = ucsi_ccg_init(uc);
246         if (status < 0) {
247                 dev_err(uc->dev, "ucsi_ccg_init failed - %d\n", status);
248                 return status;
249         }
250
251         status = devm_request_threaded_irq(dev, client->irq, NULL,
252                                            ccg_irq_handler,
253                                            IRQF_ONESHOT | IRQF_TRIGGER_HIGH,
254                                            dev_name(dev), uc);
255         if (status < 0) {
256                 dev_err(uc->dev, "request_threaded_irq failed - %d\n", status);
257                 return status;
258         }
259
260         uc->ucsi = ucsi_register_ppm(dev, &uc->ppm);
261         if (IS_ERR(uc->ucsi)) {
262                 dev_err(uc->dev, "ucsi_register_ppm failed\n");
263                 return PTR_ERR(uc->ucsi);
264         }
265
266         rab = CCGX_RAB_UCSI_DATA_BLOCK(offsetof(struct ucsi_data, version));
267         status = ccg_read(uc, rab, (u8 *)(uc->ppm.data) +
268                           offsetof(struct ucsi_data, version),
269                           sizeof(uc->ppm.data->version));
270         if (status < 0) {
271                 ucsi_unregister_ppm(uc->ucsi);
272                 return status;
273         }
274
275         i2c_set_clientdata(client, uc);
276         return 0;
277 }
278
279 static int ucsi_ccg_remove(struct i2c_client *client)
280 {
281         struct ucsi_ccg *uc = i2c_get_clientdata(client);
282
283         ucsi_unregister_ppm(uc->ucsi);
284
285         return 0;
286 }
287
288 static const struct i2c_device_id ucsi_ccg_device_id[] = {
289         {"ccgx-ucsi", 0},
290         {}
291 };
292 MODULE_DEVICE_TABLE(i2c, ucsi_ccg_device_id);
293
294 static struct i2c_driver ucsi_ccg_driver = {
295         .driver = {
296                 .name = "ucsi_ccg",
297         },
298         .probe = ucsi_ccg_probe,
299         .remove = ucsi_ccg_remove,
300         .id_table = ucsi_ccg_device_id,
301 };
302
303 module_i2c_driver(ucsi_ccg_driver);
304
305 MODULE_AUTHOR("Ajay Gupta <ajayg@nvidia.com>");
306 MODULE_DESCRIPTION("UCSI driver for Cypress CCGx Type-C controller");
307 MODULE_LICENSE("GPL v2");