Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
  1// SPDX-License-Identifier: GPL-2.0+
  2/*
  3 * Copyright (c) 2018 Google LLC
  4 * Copyright (c) 2021 Aspeed Technology Inc.
  5 */
  6#include <linux/device.h>
  7#include <linux/module.h>
  8#include <linux/of.h>
  9#include <linux/mfd/syscon.h>
 10#include <linux/regmap.h>
 11#include <linux/platform_device.h>
 12
 13/* register offsets */
 14#define HICR9	0x98
 15#define HICRA	0x9c
 16
 17/* attributes options */
 18#define UART_ROUTING_IO1	"io1"
 19#define UART_ROUTING_IO2	"io2"
 20#define UART_ROUTING_IO3	"io3"
 21#define UART_ROUTING_IO4	"io4"
 22#define UART_ROUTING_IO5	"io5"
 23#define UART_ROUTING_IO6	"io6"
 24#define UART_ROUTING_IO10	"io10"
 25#define UART_ROUTING_UART1	"uart1"
 26#define UART_ROUTING_UART2	"uart2"
 27#define UART_ROUTING_UART3	"uart3"
 28#define UART_ROUTING_UART4	"uart4"
 29#define UART_ROUTING_UART5	"uart5"
 30#define UART_ROUTING_UART6	"uart6"
 31#define UART_ROUTING_UART10	"uart10"
 32#define UART_ROUTING_RES	"reserved"
 33
 34struct aspeed_uart_routing {
 35	struct regmap *map;
 36	struct attribute_group const *attr_grp;
 37};
 38
 39struct aspeed_uart_routing_selector {
 40	struct device_attribute	dev_attr;
 41	uint8_t reg;
 42	uint8_t mask;
 43	uint8_t shift;
 44	const char *const options[];
 45};
 46
 47#define to_routing_selector(_dev_attr)					\
 48	container_of(_dev_attr, struct aspeed_uart_routing_selector, dev_attr)
 49
 50static ssize_t aspeed_uart_routing_show(struct device *dev,
 51					struct device_attribute *attr,
 52					char *buf);
 53
 54static ssize_t aspeed_uart_routing_store(struct device *dev,
 55					 struct device_attribute *attr,
 56					 const char *buf, size_t count);
 57
 58#define ROUTING_ATTR(_name) {					\
 59	.attr = {.name = _name,					\
 60		 .mode = VERIFY_OCTAL_PERMISSIONS(0644) },	\
 61	.show = aspeed_uart_routing_show,			\
 62	.store = aspeed_uart_routing_store,			\
 63}
 64
 65/* routing selector for AST25xx */
 66static struct aspeed_uart_routing_selector ast2500_io6_sel = {
 67	.dev_attr = ROUTING_ATTR(UART_ROUTING_IO6),
 68	.reg = HICR9,
 69	.shift = 8,
 70	.mask = 0xf,
 71	.options = {
 72		    UART_ROUTING_UART1,
 73		    UART_ROUTING_UART2,
 74		    UART_ROUTING_UART3,
 75		    UART_ROUTING_UART4,
 76		    UART_ROUTING_UART5,
 77		    UART_ROUTING_IO1,
 78		    UART_ROUTING_IO2,
 79		    UART_ROUTING_IO3,
 80		    UART_ROUTING_IO4,
 81		    UART_ROUTING_IO5,
 82		    NULL,
 83		    },
 84};
 85
 86static struct aspeed_uart_routing_selector ast2500_uart5_sel = {
 87	.dev_attr = ROUTING_ATTR(UART_ROUTING_UART5),
 88	.reg = HICRA,
 89	.shift = 28,
 90	.mask = 0xf,
 91	.options = {
 92		    UART_ROUTING_IO5,
 93		    UART_ROUTING_IO1,
 94		    UART_ROUTING_IO2,
 95		    UART_ROUTING_IO3,
 96		    UART_ROUTING_IO4,
 97		    UART_ROUTING_UART1,
 98		    UART_ROUTING_UART2,
 99		    UART_ROUTING_UART3,
100		    UART_ROUTING_UART4,
101		    UART_ROUTING_IO6,
102		    NULL,
103		    },
104};
105
106static struct aspeed_uart_routing_selector ast2500_uart4_sel = {
107	.dev_attr = ROUTING_ATTR(UART_ROUTING_UART4),
108	.reg = HICRA,
109	.shift = 25,
110	.mask = 0x7,
111	.options = {
112		    UART_ROUTING_IO4,
113		    UART_ROUTING_IO1,
114		    UART_ROUTING_IO2,
115		    UART_ROUTING_IO3,
116		    UART_ROUTING_UART1,
117		    UART_ROUTING_UART2,
118		    UART_ROUTING_UART3,
119		    UART_ROUTING_IO6,
120		    NULL,
121	},
122};
123
124static struct aspeed_uart_routing_selector ast2500_uart3_sel = {
125	.dev_attr = ROUTING_ATTR(UART_ROUTING_UART3),
126	.reg = HICRA,
127	.shift = 22,
128	.mask = 0x7,
129	.options = {
130		    UART_ROUTING_IO3,
131		    UART_ROUTING_IO4,
132		    UART_ROUTING_IO1,
133		    UART_ROUTING_IO2,
134		    UART_ROUTING_UART4,
135		    UART_ROUTING_UART1,
136		    UART_ROUTING_UART2,
137		    UART_ROUTING_IO6,
138		    NULL,
139		    },
140};
141
142static struct aspeed_uart_routing_selector ast2500_uart2_sel = {
143	.dev_attr = ROUTING_ATTR(UART_ROUTING_UART2),
144	.reg = HICRA,
145	.shift = 19,
146	.mask = 0x7,
147	.options = {
148		    UART_ROUTING_IO2,
149		    UART_ROUTING_IO3,
150		    UART_ROUTING_IO4,
151		    UART_ROUTING_IO1,
152		    UART_ROUTING_UART3,
153		    UART_ROUTING_UART4,
154		    UART_ROUTING_UART1,
155		    UART_ROUTING_IO6,
156		    NULL,
157		    },
158};
159
160static struct aspeed_uart_routing_selector ast2500_uart1_sel = {
161	.dev_attr = ROUTING_ATTR(UART_ROUTING_UART1),
162	.reg = HICRA,
163	.shift = 16,
164	.mask = 0x7,
165	.options = {
166		    UART_ROUTING_IO1,
167		    UART_ROUTING_IO2,
168		    UART_ROUTING_IO3,
169		    UART_ROUTING_IO4,
170		    UART_ROUTING_UART2,
171		    UART_ROUTING_UART3,
172		    UART_ROUTING_UART4,
173		    UART_ROUTING_IO6,
174		    NULL,
175		    },
176};
177
178static struct aspeed_uart_routing_selector ast2500_io5_sel = {
179	.dev_attr = ROUTING_ATTR(UART_ROUTING_IO5),
180	.reg = HICRA,
181	.shift = 12,
182	.mask = 0x7,
183	.options = {
184		    UART_ROUTING_UART5,
185		    UART_ROUTING_UART1,
186		    UART_ROUTING_UART2,
187		    UART_ROUTING_UART3,
188		    UART_ROUTING_UART4,
189		    UART_ROUTING_IO1,
190		    UART_ROUTING_IO3,
191		    UART_ROUTING_IO6,
192		    NULL,
193		    },
194};
195
196static struct aspeed_uart_routing_selector ast2500_io4_sel = {
197	.dev_attr = ROUTING_ATTR(UART_ROUTING_IO4),
198	.reg = HICRA,
199	.shift = 9,
200	.mask = 0x7,
201	.options = {
202		    UART_ROUTING_UART4,
203		    UART_ROUTING_UART5,
204		    UART_ROUTING_UART1,
205		    UART_ROUTING_UART2,
206		    UART_ROUTING_UART3,
207		    UART_ROUTING_IO1,
208		    UART_ROUTING_IO2,
209		    UART_ROUTING_IO6,
210		    NULL,
211		    },
212};
213
214static struct aspeed_uart_routing_selector ast2500_io3_sel = {
215	.dev_attr = ROUTING_ATTR(UART_ROUTING_IO3),
216	.reg = HICRA,
217	.shift = 6,
218	.mask = 0x7,
219	.options = {
220		    UART_ROUTING_UART3,
221		    UART_ROUTING_UART4,
222		    UART_ROUTING_UART5,
223		    UART_ROUTING_UART1,
224		    UART_ROUTING_UART2,
225		    UART_ROUTING_IO1,
226		    UART_ROUTING_IO2,
227		    UART_ROUTING_IO6,
228		    NULL,
229		    },
230};
231
232static struct aspeed_uart_routing_selector ast2500_io2_sel = {
233	.dev_attr = ROUTING_ATTR(UART_ROUTING_IO2),
234	.reg = HICRA,
235	.shift = 3,
236	.mask = 0x7,
237	.options = {
238		    UART_ROUTING_UART2,
239		    UART_ROUTING_UART3,
240		    UART_ROUTING_UART4,
241		    UART_ROUTING_UART5,
242		    UART_ROUTING_UART1,
243		    UART_ROUTING_IO3,
244		    UART_ROUTING_IO4,
245		    UART_ROUTING_IO6,
246		    NULL,
247		    },
248};
249
250static struct aspeed_uart_routing_selector ast2500_io1_sel = {
251	.dev_attr = ROUTING_ATTR(UART_ROUTING_IO1),
252	.reg = HICRA,
253	.shift = 0,
254	.mask = 0x7,
255	.options = {
256		    UART_ROUTING_UART1,
257		    UART_ROUTING_UART2,
258		    UART_ROUTING_UART3,
259		    UART_ROUTING_UART4,
260		    UART_ROUTING_UART5,
261		    UART_ROUTING_IO3,
262		    UART_ROUTING_IO4,
263		    UART_ROUTING_IO6,
264		    NULL,
265		    },
266};
267
268static struct attribute *ast2500_uart_routing_attrs[] = {
269	&ast2500_io6_sel.dev_attr.attr,
270	&ast2500_uart5_sel.dev_attr.attr,
271	&ast2500_uart4_sel.dev_attr.attr,
272	&ast2500_uart3_sel.dev_attr.attr,
273	&ast2500_uart2_sel.dev_attr.attr,
274	&ast2500_uart1_sel.dev_attr.attr,
275	&ast2500_io5_sel.dev_attr.attr,
276	&ast2500_io4_sel.dev_attr.attr,
277	&ast2500_io3_sel.dev_attr.attr,
278	&ast2500_io2_sel.dev_attr.attr,
279	&ast2500_io1_sel.dev_attr.attr,
280	NULL,
281};
282
283static const struct attribute_group ast2500_uart_routing_attr_group = {
284	.attrs = ast2500_uart_routing_attrs,
285};
286
287/* routing selector for AST26xx */
288static struct aspeed_uart_routing_selector ast2600_uart10_sel = {
289	.dev_attr = ROUTING_ATTR(UART_ROUTING_UART10),
290	.reg = HICR9,
291	.shift = 12,
292	.mask = 0xf,
293	.options = {
294		    UART_ROUTING_IO10,
295		    UART_ROUTING_IO1,
296		    UART_ROUTING_IO2,
297		    UART_ROUTING_IO3,
298		    UART_ROUTING_IO4,
299			UART_ROUTING_RES,
300		    UART_ROUTING_UART1,
301		    UART_ROUTING_UART2,
302		    UART_ROUTING_UART3,
303		    UART_ROUTING_UART4,
304		    NULL,
305		    },
306};
307
308static struct aspeed_uart_routing_selector ast2600_io10_sel = {
309	.dev_attr = ROUTING_ATTR(UART_ROUTING_IO10),
310	.reg = HICR9,
311	.shift = 8,
312	.mask = 0xf,
313	.options = {
314		    UART_ROUTING_UART1,
315		    UART_ROUTING_UART2,
316		    UART_ROUTING_UART3,
317		    UART_ROUTING_UART4,
318			UART_ROUTING_RES,
319		    UART_ROUTING_IO1,
320		    UART_ROUTING_IO2,
321		    UART_ROUTING_IO3,
322		    UART_ROUTING_IO4,
323			UART_ROUTING_RES,
324		    UART_ROUTING_UART10,
325		    NULL,
326		    },
327};
328
329static struct aspeed_uart_routing_selector ast2600_uart4_sel = {
330	.dev_attr = ROUTING_ATTR(UART_ROUTING_UART4),
331	.reg = HICRA,
332	.shift = 25,
333	.mask = 0x7,
334	.options = {
335		    UART_ROUTING_IO4,
336		    UART_ROUTING_IO1,
337		    UART_ROUTING_IO2,
338		    UART_ROUTING_IO3,
339		    UART_ROUTING_UART1,
340		    UART_ROUTING_UART2,
341		    UART_ROUTING_UART3,
342		    UART_ROUTING_IO10,
343		    NULL,
344	},
345};
346
347static struct aspeed_uart_routing_selector ast2600_uart3_sel = {
348	.dev_attr = ROUTING_ATTR(UART_ROUTING_UART3),
349	.reg = HICRA,
350	.shift = 22,
351	.mask = 0x7,
352	.options = {
353		    UART_ROUTING_IO3,
354		    UART_ROUTING_IO4,
355		    UART_ROUTING_IO1,
356		    UART_ROUTING_IO2,
357		    UART_ROUTING_UART4,
358		    UART_ROUTING_UART1,
359		    UART_ROUTING_UART2,
360		    UART_ROUTING_IO10,
361		    NULL,
362		    },
363};
364
365static struct aspeed_uart_routing_selector ast2600_uart2_sel = {
366	.dev_attr = ROUTING_ATTR(UART_ROUTING_UART2),
367	.reg = HICRA,
368	.shift = 19,
369	.mask = 0x7,
370	.options = {
371		    UART_ROUTING_IO2,
372		    UART_ROUTING_IO3,
373		    UART_ROUTING_IO4,
374		    UART_ROUTING_IO1,
375		    UART_ROUTING_UART3,
376		    UART_ROUTING_UART4,
377		    UART_ROUTING_UART1,
378		    UART_ROUTING_IO10,
379		    NULL,
380		    },
381};
382
383static struct aspeed_uart_routing_selector ast2600_uart1_sel = {
384	.dev_attr = ROUTING_ATTR(UART_ROUTING_UART1),
385	.reg = HICRA,
386	.shift = 16,
387	.mask = 0x7,
388	.options = {
389		    UART_ROUTING_IO1,
390		    UART_ROUTING_IO2,
391		    UART_ROUTING_IO3,
392		    UART_ROUTING_IO4,
393		    UART_ROUTING_UART2,
394		    UART_ROUTING_UART3,
395		    UART_ROUTING_UART4,
396		    UART_ROUTING_IO10,
397		    NULL,
398		    },
399};
400
401static struct aspeed_uart_routing_selector ast2600_io4_sel = {
402	.dev_attr = ROUTING_ATTR(UART_ROUTING_IO4),
403	.reg = HICRA,
404	.shift = 9,
405	.mask = 0x7,
406	.options = {
407		    UART_ROUTING_UART4,
408		    UART_ROUTING_UART10,
409		    UART_ROUTING_UART1,
410		    UART_ROUTING_UART2,
411		    UART_ROUTING_UART3,
412		    UART_ROUTING_IO1,
413		    UART_ROUTING_IO2,
414		    UART_ROUTING_IO10,
415		    NULL,
416		    },
417};
418
419static struct aspeed_uart_routing_selector ast2600_io3_sel = {
420	.dev_attr = ROUTING_ATTR(UART_ROUTING_IO3),
421	.reg = HICRA,
422	.shift = 6,
423	.mask = 0x7,
424	.options = {
425		    UART_ROUTING_UART3,
426		    UART_ROUTING_UART4,
427		    UART_ROUTING_UART10,
428		    UART_ROUTING_UART1,
429		    UART_ROUTING_UART2,
430		    UART_ROUTING_IO1,
431		    UART_ROUTING_IO2,
432		    UART_ROUTING_IO10,
433		    NULL,
434		    },
435};
436
437static struct aspeed_uart_routing_selector ast2600_io2_sel = {
438	.dev_attr = ROUTING_ATTR(UART_ROUTING_IO2),
439	.reg = HICRA,
440	.shift = 3,
441	.mask = 0x7,
442	.options = {
443		    UART_ROUTING_UART2,
444		    UART_ROUTING_UART3,
445		    UART_ROUTING_UART4,
446		    UART_ROUTING_UART10,
447		    UART_ROUTING_UART1,
448		    UART_ROUTING_IO3,
449		    UART_ROUTING_IO4,
450		    UART_ROUTING_IO10,
451		    NULL,
452		    },
453};
454
455static struct aspeed_uart_routing_selector ast2600_io1_sel = {
456	.dev_attr = ROUTING_ATTR(UART_ROUTING_IO1),
457	.reg = HICRA,
458	.shift = 0,
459	.mask = 0x7,
460	.options = {
461		    UART_ROUTING_UART1,
462		    UART_ROUTING_UART2,
463		    UART_ROUTING_UART3,
464		    UART_ROUTING_UART4,
465		    UART_ROUTING_UART10,
466		    UART_ROUTING_IO3,
467		    UART_ROUTING_IO4,
468		    UART_ROUTING_IO10,
469		    NULL,
470		    },
471};
472
473static struct attribute *ast2600_uart_routing_attrs[] = {
474	&ast2600_uart10_sel.dev_attr.attr,
475	&ast2600_io10_sel.dev_attr.attr,
476	&ast2600_uart4_sel.dev_attr.attr,
477	&ast2600_uart3_sel.dev_attr.attr,
478	&ast2600_uart2_sel.dev_attr.attr,
479	&ast2600_uart1_sel.dev_attr.attr,
480	&ast2600_io4_sel.dev_attr.attr,
481	&ast2600_io3_sel.dev_attr.attr,
482	&ast2600_io2_sel.dev_attr.attr,
483	&ast2600_io1_sel.dev_attr.attr,
484	NULL,
485};
486
487static const struct attribute_group ast2600_uart_routing_attr_group = {
488	.attrs = ast2600_uart_routing_attrs,
489};
490
491static ssize_t aspeed_uart_routing_show(struct device *dev,
492					struct device_attribute *attr,
493					char *buf)
494{
495	struct aspeed_uart_routing *uart_routing = dev_get_drvdata(dev);
496	struct aspeed_uart_routing_selector *sel = to_routing_selector(attr);
497	int val, pos, len;
498
499	regmap_read(uart_routing->map, sel->reg, &val);
500	val = (val >> sel->shift) & sel->mask;
501
502	len = 0;
503	for (pos = 0; sel->options[pos] != NULL; ++pos) {
504		if (pos == val)
505			len += sysfs_emit_at(buf, len, "[%s] ", sel->options[pos]);
506		else
507			len += sysfs_emit_at(buf, len, "%s ", sel->options[pos]);
508	}
509
510	if (val >= pos)
511		len += sysfs_emit_at(buf, len, "[unknown(%d)]", val);
512
513	len += sysfs_emit_at(buf, len, "\n");
514
515	return len;
516}
517
518static ssize_t aspeed_uart_routing_store(struct device *dev,
519					 struct device_attribute *attr,
520					 const char *buf, size_t count)
521{
522	struct aspeed_uart_routing *uart_routing = dev_get_drvdata(dev);
523	struct aspeed_uart_routing_selector *sel = to_routing_selector(attr);
524	int val;
525
526	val = __sysfs_match_string(sel->options, -1, buf);
527	if (val < 0) {
528		dev_err(dev, "invalid value \"%s\"\n", buf);
529		return -EINVAL;
530	}
531
532	regmap_update_bits(uart_routing->map, sel->reg,
533			(sel->mask << sel->shift),
534			(val & sel->mask) << sel->shift);
535
536	return count;
537}
538
539static int aspeed_uart_routing_probe(struct platform_device *pdev)
540{
541	int rc;
542	struct device *dev = &pdev->dev;
543	struct aspeed_uart_routing *uart_routing;
544
545	uart_routing = devm_kzalloc(&pdev->dev, sizeof(*uart_routing), GFP_KERNEL);
546	if (!uart_routing)
547		return -ENOMEM;
548
549	uart_routing->map = syscon_node_to_regmap(dev->parent->of_node);
550	if (IS_ERR(uart_routing->map)) {
551		dev_err(dev, "cannot get regmap\n");
552		return PTR_ERR(uart_routing->map);
553	}
554
555	uart_routing->attr_grp = of_device_get_match_data(dev);
556
557	rc = sysfs_create_group(&dev->kobj, uart_routing->attr_grp);
558	if (rc < 0)
559		return rc;
560
561	dev_set_drvdata(dev, uart_routing);
562
563	dev_info(dev, "module loaded\n");
564
565	return 0;
566}
567
568static void aspeed_uart_routing_remove(struct platform_device *pdev)
569{
570	struct device *dev = &pdev->dev;
571	struct aspeed_uart_routing *uart_routing = platform_get_drvdata(pdev);
572
573	sysfs_remove_group(&dev->kobj, uart_routing->attr_grp);
574}
575
576static const struct of_device_id aspeed_uart_routing_table[] = {
577	{ .compatible = "aspeed,ast2400-uart-routing",
578	  .data = &ast2500_uart_routing_attr_group },
579	{ .compatible = "aspeed,ast2500-uart-routing",
580	  .data = &ast2500_uart_routing_attr_group },
581	{ .compatible = "aspeed,ast2600-uart-routing",
582	  .data = &ast2600_uart_routing_attr_group },
583	{ },
584};
585
586static struct platform_driver aspeed_uart_routing_driver = {
587	.driver = {
588		.name = "aspeed-uart-routing",
589		.of_match_table = aspeed_uart_routing_table,
590	},
591	.probe = aspeed_uart_routing_probe,
592	.remove_new = aspeed_uart_routing_remove,
593};
594
595module_platform_driver(aspeed_uart_routing_driver);
596
597MODULE_AUTHOR("Oskar Senft <osk@google.com>");
598MODULE_AUTHOR("Chia-Wei Wang <chiawei_wang@aspeedtech.com>");
599MODULE_LICENSE("GPL v2");
600MODULE_DESCRIPTION("Driver to configure Aspeed UART routing");