1
2
3
4
5
6
7#include <linux/module.h>
8#include <linux/regmap.h>
9#include <linux/spi/spi.h>
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55#define PKT_SOP 0x7a
56#define PKT_EOP 0x7b
57#define PKT_CHANNEL 0x7c
58#define PKT_ESC 0x7d
59
60#define PHY_IDLE 0x4a
61#define PHY_ESC 0x4d
62
63#define TRANS_CODE_WRITE 0x0
64#define TRANS_CODE_SEQ_WRITE 0x4
65#define TRANS_CODE_READ 0x10
66#define TRANS_CODE_SEQ_READ 0x14
67#define TRANS_CODE_NO_TRANS 0x7f
68
69#define SPI_AVMM_XFER_TIMEOUT (msecs_to_jiffies(200))
70
71
72#define SPI_AVMM_REG_SIZE 4UL
73
74#define SPI_AVMM_VAL_SIZE 4UL
75
76
77
78
79
80#define MAX_READ_CNT 256UL
81#define MAX_WRITE_CNT 1UL
82
83struct trans_req_header {
84 u8 code;
85 u8 rsvd;
86 __be16 size;
87 __be32 addr;
88} __packed;
89
90struct trans_resp_header {
91 u8 r_code;
92 u8 rsvd;
93 __be16 size;
94} __packed;
95
96#define TRANS_REQ_HD_SIZE (sizeof(struct trans_req_header))
97#define TRANS_RESP_HD_SIZE (sizeof(struct trans_resp_header))
98
99
100
101
102
103
104
105
106#define TRANS_WR_TX_SIZE(n) (TRANS_REQ_HD_SIZE + SPI_AVMM_VAL_SIZE * (n))
107#define TRANS_RD_TX_SIZE TRANS_REQ_HD_SIZE
108#define TRANS_TX_MAX TRANS_WR_TX_SIZE(MAX_WRITE_CNT)
109
110#define TRANS_RD_RX_SIZE(n) (SPI_AVMM_VAL_SIZE * (n))
111#define TRANS_WR_RX_SIZE TRANS_RESP_HD_SIZE
112#define TRANS_RX_MAX TRANS_RD_RX_SIZE(MAX_READ_CNT)
113
114
115#define TRANS_BUF_SIZE ((TRANS_TX_MAX > TRANS_RX_MAX) ? \
116 TRANS_TX_MAX : TRANS_RX_MAX)
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132#define PHY_TX_MAX ALIGN(2 * TRANS_TX_MAX + 4, 4)
133
134
135
136
137
138
139
140#define PHY_BUF_SIZE PHY_TX_MAX
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157struct spi_avmm_bridge {
158 struct spi_device *spi;
159 unsigned char word_len;
160 unsigned int trans_len;
161 unsigned int phy_len;
162
163 char trans_buf[TRANS_BUF_SIZE];
164 char phy_buf[PHY_BUF_SIZE];
165 void (*swap_words)(char *buf, unsigned int len);
166};
167
168static void br_swap_words_32(char *buf, unsigned int len)
169{
170 u32 *p = (u32 *)buf;
171 unsigned int count;
172
173 count = len / 4;
174 while (count--) {
175 *p = swab32p(p);
176 p++;
177 }
178}
179
180
181
182
183
184static int br_trans_tx_prepare(struct spi_avmm_bridge *br, bool is_read, u32 reg,
185 u32 *wr_val, u32 count)
186{
187 struct trans_req_header *header;
188 unsigned int trans_len;
189 u8 code;
190 __le32 *data;
191 int i;
192
193 if (is_read) {
194 if (count == 1)
195 code = TRANS_CODE_READ;
196 else
197 code = TRANS_CODE_SEQ_READ;
198 } else {
199 if (count == 1)
200 code = TRANS_CODE_WRITE;
201 else
202 code = TRANS_CODE_SEQ_WRITE;
203 }
204
205 header = (struct trans_req_header *)br->trans_buf;
206 header->code = code;
207 header->rsvd = 0;
208 header->size = cpu_to_be16((u16)count * SPI_AVMM_VAL_SIZE);
209 header->addr = cpu_to_be32(reg);
210
211 trans_len = TRANS_REQ_HD_SIZE;
212
213 if (!is_read) {
214 trans_len += SPI_AVMM_VAL_SIZE * count;
215 if (trans_len > sizeof(br->trans_buf))
216 return -ENOMEM;
217
218 data = (__le32 *)(br->trans_buf + TRANS_REQ_HD_SIZE);
219
220 for (i = 0; i < count; i++)
221 *data++ = cpu_to_le32(*wr_val++);
222 }
223
224
225 br->trans_len = trans_len;
226
227 return 0;
228}
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253static int br_pkt_phy_tx_prepare(struct spi_avmm_bridge *br)
254{
255 char *tb, *tb_end, *pb, *pb_limit, *pb_eop = NULL;
256 unsigned int aligned_phy_len, move_size;
257 bool need_esc = false;
258
259 tb = br->trans_buf;
260 tb_end = tb + br->trans_len;
261 pb = br->phy_buf;
262 pb_limit = pb + ARRAY_SIZE(br->phy_buf);
263
264 *pb++ = PKT_SOP;
265
266
267
268
269
270 *pb++ = PKT_CHANNEL;
271 *pb++ = 0x0;
272
273 for (; pb < pb_limit && tb < tb_end; pb++) {
274 if (need_esc) {
275 *pb = *tb++ ^ 0x20;
276 need_esc = false;
277 continue;
278 }
279
280
281 if (tb == tb_end - 1 && !pb_eop) {
282 *pb = PKT_EOP;
283 pb_eop = pb;
284 continue;
285 }
286
287
288
289
290
291 switch (*tb) {
292 case PKT_SOP:
293 case PKT_EOP:
294 case PKT_CHANNEL:
295 case PKT_ESC:
296 *pb = PKT_ESC;
297 need_esc = true;
298 break;
299 case PHY_IDLE:
300 case PHY_ESC:
301 *pb = PHY_ESC;
302 need_esc = true;
303 break;
304 default:
305 *pb = *tb++;
306 break;
307 }
308 }
309
310
311 if (tb < tb_end)
312 return -ENOMEM;
313
314
315 br->phy_len = pb - br->phy_buf;
316
317 if (br->word_len == 1)
318 return 0;
319
320
321 aligned_phy_len = ALIGN(br->phy_len, br->word_len);
322 if (aligned_phy_len > sizeof(br->phy_buf))
323 return -ENOMEM;
324
325 if (aligned_phy_len == br->phy_len)
326 return 0;
327
328
329 move_size = pb - pb_eop;
330 memmove(&br->phy_buf[aligned_phy_len - move_size], pb_eop, move_size);
331
332
333 memset(pb_eop, PHY_IDLE, aligned_phy_len - br->phy_len);
334
335
336 br->phy_len = aligned_phy_len;
337
338 return 0;
339}
340
341
342
343
344
345static int br_do_tx(struct spi_avmm_bridge *br)
346{
347
348 if (br->swap_words)
349 br->swap_words(br->phy_buf, br->phy_len);
350
351
352 return spi_write(br->spi, br->phy_buf, br->phy_len);
353}
354
355
356
357
358
359
360
361
362
363
364
365static int br_do_rx_and_pkt_phy_parse(struct spi_avmm_bridge *br)
366{
367 bool eop_found = false, channel_found = false, esc_found = false;
368 bool valid_word = false, last_try = false;
369 struct device *dev = &br->spi->dev;
370 char *pb, *tb_limit, *tb = NULL;
371 unsigned long poll_timeout;
372 int ret, i;
373
374 tb_limit = br->trans_buf + ARRAY_SIZE(br->trans_buf);
375 pb = br->phy_buf;
376 poll_timeout = jiffies + SPI_AVMM_XFER_TIMEOUT;
377 while (tb < tb_limit) {
378 ret = spi_read(br->spi, pb, br->word_len);
379 if (ret)
380 return ret;
381
382
383 if (br->swap_words)
384 br->swap_words(pb, br->word_len);
385
386 valid_word = false;
387 for (i = 0; i < br->word_len; i++) {
388
389 if (!tb && pb[i] != PKT_SOP)
390 continue;
391
392
393 if (pb[i] == PHY_IDLE)
394 continue;
395
396 valid_word = true;
397
398
399
400
401
402 if (channel_found) {
403 if (pb[i] != 0) {
404 dev_err(dev, "%s channel num != 0\n",
405 __func__);
406 return -EFAULT;
407 }
408
409 channel_found = false;
410 continue;
411 }
412
413 switch (pb[i]) {
414 case PKT_SOP:
415
416
417
418 tb = br->trans_buf;
419 eop_found = false;
420 channel_found = false;
421 esc_found = false;
422 break;
423 case PKT_EOP:
424
425
426
427
428
429
430
431 if (esc_found || eop_found)
432 return -EFAULT;
433
434 eop_found = true;
435 break;
436 case PKT_CHANNEL:
437 if (esc_found || eop_found)
438 return -EFAULT;
439
440 channel_found = true;
441 break;
442 case PKT_ESC:
443 case PHY_ESC:
444 if (esc_found)
445 return -EFAULT;
446
447 esc_found = true;
448 break;
449 default:
450
451 if (esc_found) {
452 *tb++ = pb[i] ^ 0x20;
453 esc_found = false;
454 } else {
455 *tb++ = pb[i];
456 }
457
458
459
460
461
462
463 if (eop_found) {
464 br->trans_len = tb - br->trans_buf;
465 return 0;
466 }
467 }
468 }
469
470 if (valid_word) {
471
472 poll_timeout = jiffies + SPI_AVMM_XFER_TIMEOUT;
473 last_try = false;
474 } else {
475
476
477
478
479
480
481
482
483
484 if (last_try)
485 return -ETIMEDOUT;
486
487 if (time_after(jiffies, poll_timeout))
488 last_try = true;
489 }
490 }
491
492
493
494
495
496 dev_err(dev, "%s transfer buffer is full but rx doesn't end\n",
497 __func__);
498
499 return -EFAULT;
500}
501
502
503
504
505
506static int br_rd_trans_rx_parse(struct spi_avmm_bridge *br,
507 u32 *val, unsigned int expected_count)
508{
509 unsigned int i, trans_len = br->trans_len;
510 __le32 *data;
511
512 if (expected_count * SPI_AVMM_VAL_SIZE != trans_len)
513 return -EFAULT;
514
515 data = (__le32 *)br->trans_buf;
516 for (i = 0; i < expected_count; i++)
517 *val++ = le32_to_cpu(*data++);
518
519 return 0;
520}
521
522
523
524
525
526static int br_wr_trans_rx_parse(struct spi_avmm_bridge *br,
527 unsigned int expected_count)
528{
529 unsigned int trans_len = br->trans_len;
530 struct trans_resp_header *resp;
531 u8 code;
532 u16 val_len;
533
534 if (trans_len != TRANS_RESP_HD_SIZE)
535 return -EFAULT;
536
537 resp = (struct trans_resp_header *)br->trans_buf;
538
539 code = resp->r_code ^ 0x80;
540 val_len = be16_to_cpu(resp->size);
541 if (!val_len || val_len != expected_count * SPI_AVMM_VAL_SIZE)
542 return -EFAULT;
543
544
545 if ((val_len == SPI_AVMM_VAL_SIZE && code != TRANS_CODE_WRITE) ||
546 (val_len > SPI_AVMM_VAL_SIZE && code != TRANS_CODE_SEQ_WRITE))
547 return -EFAULT;
548
549 return 0;
550}
551
552static int do_reg_access(void *context, bool is_read, unsigned int reg,
553 unsigned int *value, unsigned int count)
554{
555 struct spi_avmm_bridge *br = context;
556 int ret;
557
558
559 br->trans_len = 0;
560 br->phy_len = 0;
561
562 ret = br_trans_tx_prepare(br, is_read, reg, value, count);
563 if (ret)
564 return ret;
565
566 ret = br_pkt_phy_tx_prepare(br);
567 if (ret)
568 return ret;
569
570 ret = br_do_tx(br);
571 if (ret)
572 return ret;
573
574 ret = br_do_rx_and_pkt_phy_parse(br);
575 if (ret)
576 return ret;
577
578 if (is_read)
579 return br_rd_trans_rx_parse(br, value, count);
580 else
581 return br_wr_trans_rx_parse(br, count);
582}
583
584static int regmap_spi_avmm_gather_write(void *context,
585 const void *reg_buf, size_t reg_len,
586 const void *val_buf, size_t val_len)
587{
588 if (reg_len != SPI_AVMM_REG_SIZE)
589 return -EINVAL;
590
591 if (!IS_ALIGNED(val_len, SPI_AVMM_VAL_SIZE))
592 return -EINVAL;
593
594 return do_reg_access(context, false, *(u32 *)reg_buf, (u32 *)val_buf,
595 val_len / SPI_AVMM_VAL_SIZE);
596}
597
598static int regmap_spi_avmm_write(void *context, const void *data, size_t bytes)
599{
600 if (bytes < SPI_AVMM_REG_SIZE + SPI_AVMM_VAL_SIZE)
601 return -EINVAL;
602
603 return regmap_spi_avmm_gather_write(context, data, SPI_AVMM_REG_SIZE,
604 data + SPI_AVMM_REG_SIZE,
605 bytes - SPI_AVMM_REG_SIZE);
606}
607
608static int regmap_spi_avmm_read(void *context,
609 const void *reg_buf, size_t reg_len,
610 void *val_buf, size_t val_len)
611{
612 if (reg_len != SPI_AVMM_REG_SIZE)
613 return -EINVAL;
614
615 if (!IS_ALIGNED(val_len, SPI_AVMM_VAL_SIZE))
616 return -EINVAL;
617
618 return do_reg_access(context, true, *(u32 *)reg_buf, val_buf,
619 (val_len / SPI_AVMM_VAL_SIZE));
620}
621
622static struct spi_avmm_bridge *
623spi_avmm_bridge_ctx_gen(struct spi_device *spi)
624{
625 struct spi_avmm_bridge *br;
626
627 if (!spi)
628 return ERR_PTR(-ENODEV);
629
630
631 spi->mode = SPI_MODE_1;
632 spi->bits_per_word = 32;
633 if (spi_setup(spi)) {
634 spi->bits_per_word = 8;
635 if (spi_setup(spi))
636 return ERR_PTR(-EINVAL);
637 }
638
639 br = kzalloc(sizeof(*br), GFP_KERNEL);
640 if (!br)
641 return ERR_PTR(-ENOMEM);
642
643 br->spi = spi;
644 br->word_len = spi->bits_per_word / 8;
645 if (br->word_len == 4) {
646
647
648
649
650
651 br->swap_words = br_swap_words_32;
652 }
653
654 return br;
655}
656
657static void spi_avmm_bridge_ctx_free(void *context)
658{
659 kfree(context);
660}
661
662static const struct regmap_bus regmap_spi_avmm_bus = {
663 .write = regmap_spi_avmm_write,
664 .gather_write = regmap_spi_avmm_gather_write,
665 .read = regmap_spi_avmm_read,
666 .reg_format_endian_default = REGMAP_ENDIAN_NATIVE,
667 .val_format_endian_default = REGMAP_ENDIAN_NATIVE,
668 .max_raw_read = SPI_AVMM_VAL_SIZE * MAX_READ_CNT,
669 .max_raw_write = SPI_AVMM_VAL_SIZE * MAX_WRITE_CNT,
670 .free_context = spi_avmm_bridge_ctx_free,
671};
672
673struct regmap *__regmap_init_spi_avmm(struct spi_device *spi,
674 const struct regmap_config *config,
675 struct lock_class_key *lock_key,
676 const char *lock_name)
677{
678 struct spi_avmm_bridge *bridge;
679 struct regmap *map;
680
681 bridge = spi_avmm_bridge_ctx_gen(spi);
682 if (IS_ERR(bridge))
683 return ERR_CAST(bridge);
684
685 map = __regmap_init(&spi->dev, ®map_spi_avmm_bus,
686 bridge, config, lock_key, lock_name);
687 if (IS_ERR(map)) {
688 spi_avmm_bridge_ctx_free(bridge);
689 return ERR_CAST(map);
690 }
691
692 return map;
693}
694EXPORT_SYMBOL_GPL(__regmap_init_spi_avmm);
695
696struct regmap *__devm_regmap_init_spi_avmm(struct spi_device *spi,
697 const struct regmap_config *config,
698 struct lock_class_key *lock_key,
699 const char *lock_name)
700{
701 struct spi_avmm_bridge *bridge;
702 struct regmap *map;
703
704 bridge = spi_avmm_bridge_ctx_gen(spi);
705 if (IS_ERR(bridge))
706 return ERR_CAST(bridge);
707
708 map = __devm_regmap_init(&spi->dev, ®map_spi_avmm_bus,
709 bridge, config, lock_key, lock_name);
710 if (IS_ERR(map)) {
711 spi_avmm_bridge_ctx_free(bridge);
712 return ERR_CAST(map);
713 }
714
715 return map;
716}
717EXPORT_SYMBOL_GPL(__devm_regmap_init_spi_avmm);
718
719MODULE_LICENSE("GPL v2");
720