Linux Audio

Check our new training course

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