2 // #define pr_fmt(fmt) "---sprd pinswitch---"fmt
5 #include <linux/module.h>
6 #include <linux/platform_device.h>
7 #include <linux/proc_fs.h>
8 #include <linux/seq_file.h>
9 #include <asm/uaccess.h>
10 #include <linux/printk.h>
11 #include <soc/sprd/hardware.h>
12 #include <soc/sprd/arch_lock.h>
14 #include <soc/sprd/pin_switch.h>
15 #include <linux/regulator/consumer.h>
20 unsigned long SPRD_PIN_BASE = 0;
21 struct sci_pin_switch {
30 static struct sci_pin_switch sci_pin_switch_array[] = {
31 #if !(defined(CONFIG_ARCH_SCX15)||defined(CONFIG_ARCH_SCX35L))
32 {"", "vbc_dac_iislrck_pin_in_sel", 0x4, 24, 1, 0},
33 {"", "vbc_dac_iisclk_pin_in_sel", 0x4, 23, 1, 0},
34 {"", "vbc_adc_iislrck_pin_in_sel", 0x4, 22, 1, 0},
35 {"", "vbc_adc_iisdi_pin_in_sel", 0x4, 21, 1, 0},
36 {"", "vbc_adc_iisclk_pin_in_sel", 0x4, 20, 1, 0},
37 {"", "iis3mck_pin_in_sel", 0x4, 19, 1, 0},
38 {"", "iis3lrck_pin_in_sel", 0x4, 18, 1, 0},
39 {"", "iis3di_pin_in_sel", 0x4, 17, 1, 0},
40 {"", "iis3clk_pin_in_sel", 0x4, 16, 1, 0},
41 {"", "iis2mck_pin_in_sel", 0x4, 15, 1, 0},
42 {"", "iis2lrck_pin_in_sel", 0x4, 14, 1, 0},
43 {"", "iis2di_pin_in_sel", 0x4, 13, 1, 0},
44 {"", "iis2clk_pin_in_sel", 0x4, 12, 1, 0},
45 #if defined(CONFIG_ARCH_SCX30G) /*tshark add */
46 {"", "bt_iis_con_eb", 0xc, 30, 1, 0},
47 {"", "pad_oe_iis3_mck", 0xc, 27, 1, 0},
48 {"", "pad_oe_iis2_mck", 0xc, 26, 1, 0},
49 {"", "pad_oe_iis1_mck", 0xc, 25, 1, 0},
50 {"", "pad_oe_iis0_mck", 0xc, 24, 1, 0},
53 {"", "iis23_loop_sel", 0xc, 5, 1, 0},
54 {"", "iis13_loop_sel", 0xc, 4, 1, 0},
55 {"", "iis12_loop_sel", 0xc, 3, 1, 0},
56 {"", "iis03_loop_sel", 0xc, 2, 1, 0},
57 {"", "iis02_loop_sel", 0xc, 1, 1, 0},
58 {"", "iis01_loop_sel", 0xc, 0, 1, 0},
62 #if defined(CONFIG_ARCH_SCX35L)
63 static struct sci_pin_switch iis_0_array[] = {
64 {"iis0_sys_sel", "ap_iis0", 0xc, 6, 3, 0},
65 {"iis0_sys_sel", "cp0_iis0", 0xc, 6, 3, 1},
66 {"iis0_sys_sel", "cp1_iis0", 0xc, 6, 3, 2},
67 {"iis0_sys_sel", "vbc_iis0", 0xc, 6, 3, 3},
68 {"iis0_sys_sel", "vbc_iis1", 0xc, 6, 3, 4},
71 static struct sci_pin_switch iis_1_array[] = {
72 {"iis1_sys_sel", "ap_iis1", 0xc, 9, 3, 0},
73 {"iis1_sys_sel", "cp0_iis1", 0xc, 9, 3, 1},
74 {"iis1_sys_sel", "cp1_iis1", 0xc, 9, 3, 2},
75 {"iis1_sys_sel", "vbc_iis0", 0xc, 9, 3, 3},
76 {"iis1_sys_sel", "vbc_iis1", 0xc, 9, 3, 4},
79 static struct sci_pin_switch iis_2_array[] = {
80 {"iis2_sys_sel", "ap_iis2", 0xc, 12, 3, 0},
81 {"iis2_sys_sel", "cp0_iis2", 0xc, 12, 3, 1},
82 {"iis2_sys_sel", "cp1_iis2", 0xc, 12, 3, 2},
83 {"iis2_sys_sel", "vbc_iis0", 0xc, 12, 3, 3},
84 {"iis2_sys_sel", "vbc_iis1", 0xc, 12, 3, 4},
87 static struct sci_pin_switch iis_3_array[] = {
88 {"iis3_sys_sel", "ap_iis3", 0xc, 15, 3, 0},
89 {"iis3_sys_sel", "cp0_iis3", 0xc, 15, 3, 1},
90 {"iis3_sys_sel", "cp1_iis3", 0xc, 15, 3, 2},
91 {"iis3_sys_sel", "vbc_iis0", 0xc, 15, 3, 3},
92 {"iis3_sys_sel", "vbc_iis1", 0xc, 15, 3, 4},
95 static struct sci_pin_switch bt_iis_sys_sel_array[] = {
96 {"bt_iis_sys_sel", "cp0_iis0", 0x8, 28, 4, 0},
97 {"bt_iis_sys_sel", "cp0_iis1", 0x8, 28, 4, 1},
98 {"bt_iis_sys_sel", "cp0_iis2", 0x8, 28, 4, 2},
99 {"bt_iis_sys_sel", "cp0_iis3", 0x8, 28, 4, 3},
100 {"bt_iis_sys_sel", "cp1_iis0", 0x8, 28, 4, 4},
101 {"bt_iis_sys_sel", "cp1_iis1", 0x8, 28, 4, 5},
102 {"bt_iis_sys_sel", "cp1_iis2", 0x8, 28, 4, 6},
103 {"bt_iis_sys_sel", "cp1_iis3", 0x8, 28, 4, 7},
104 {"bt_iis_sys_sel", "ap_iis0", 0x8, 28, 4, 8},
105 {"bt_iis_sys_sel", "ap_iis1", 0x8, 28, 4, 9},
106 {"bt_iis_sys_sel", "ap_iis2", 0x8, 28, 4, 10},
107 {"bt_iis_sys_sel", "ap_iis3", 0x8, 28, 4, 11},
108 {"bt_iis_sys_sel", "vbc_iis", 0x8, 28, 4, 12},
109 {"bt_iis_sys_sel", "rsv_d", 0x8, 28, 4, 13},
110 {"bt_iis_sys_sel", "rsv_e", 0x8, 28, 4, 14},
111 {"bt_iis_sys_sel", "rsv_f", 0x8, 28, 4, 15},
114 static struct sci_pin_switch iis_0_array[] = {
115 {"iis0_sys_sel", "ap_iis0", 0xc, 6, 2, 0},
116 {"iis0_sys_sel", "cp0_iis0", 0xc, 6, 2, 1},
117 {"iis0_sys_sel", "cp1_iis0", 0xc, 6, 2, 2},
118 {"iis0_sys_sel", "cp2_iis0", 0xc, 6, 2, 3},
119 {"iis0_sys_sel", "vbc_iis0", 0xc, 6, 3, 4},
122 static struct sci_pin_switch iis_1_array[] = {
123 {"iis1_sys_sel", "ap_iis1", 0xc, 9, 2, 0},
124 {"iis1_sys_sel", "cp0_iis1", 0xc, 9, 2, 1},
125 {"iis1_sys_sel", "cp1_iis1", 0xc, 9, 2, 2},
126 {"iis1_sys_sel", "cp2_iis1", 0xc, 9, 2, 3},
129 #if !defined(CONFIG_ARCH_SCX15)
130 static struct sci_pin_switch iis_2_array[] = {
131 {"iis2_sys_sel", "ap_iis2", 0xc, 12, 2, 0},
132 {"iis2_sys_sel", "cp0_iis2", 0xc, 12, 2, 1},
133 {"iis2_sys_sel", "cp1_iis2", 0xc, 12, 2, 2},
134 {"iis2_sys_sel", "cp2_iis2", 0xc, 12, 2, 3},
137 static struct sci_pin_switch iis_3_array[] = {
138 {"iis3_sys_sel", "ap_iis3", 0xc, 15, 2, 0},
139 {"iis3_sys_sel", "cp0_iis3", 0xc, 15, 2, 1},
140 {"iis3_sys_sel", "cp1_iis3", 0xc, 15, 2, 2},
141 {"iis3_sys_sel", "cp2_iis3", 0xc, 15, 2, 3},
146 #if defined(CONFIG_PIN_POWER_DOMAIN_SWITCH)
147 struct pin_reg_desc {
148 struct sprd_pin_switch_platform_data *platform_data;
149 struct notifier_block nb;
150 struct regulator_bulk_data supplies;
151 } pin_reg_desc_array[PD_CNT];
154 static struct sci_pin_switch_dir {
155 struct sci_pin_switch *sci_pin_switch;
157 } sci_pin_switch_dir_array[] = {
158 #if !defined(CONFIG_ARCH_SCX35L)
160 bt_iis_sys_sel_array, ARRAY_SIZE(bt_iis_sys_sel_array)},
163 iis_0_array, ARRAY_SIZE(iis_0_array)}, {
164 iis_1_array, ARRAY_SIZE(iis_1_array)},
165 #if !defined(CONFIG_ARCH_SCX15)
167 iis_2_array, ARRAY_SIZE(iis_2_array)}, {
168 iis_3_array, ARRAY_SIZE(iis_3_array)},
172 u32 pinmap_get(u32 offset)
174 return readl(SPRD_PIN_BASE + offset);
177 EXPORT_SYMBOL(pinmap_get);
178 int pinmap_set(u32 offset, u32 value)
181 __arch_default_lock(HWLOCK_GLB, &flags);
182 writel(value, SPRD_PIN_BASE + offset);
183 __arch_default_unlock(HWLOCK_GLB, &flags);
187 EXPORT_SYMBOL(pinmap_set);
190 * #define IIS_TO_AP (0)
191 * #define IIS_TO_CP0 (1)
192 * #define IIS_TO_CP1 (2)
193 * #define IIS_TO_CP2 (3)
194 * #define PIN_CTL_REG3 (SPRD_PIN_BASE + 0xc)
196 static int read_write_pin_switch(int is_read, int v, struct sci_pin_switch *p)
199 u32 shift = p->bit_offset;
200 u32 mask = (1 << (p->bit_width)) - 1;
204 printk("v:0x%x overflow bitwidth:%ud, mask:0x%x it\n",
205 v, p->bit_width, mask);
206 val = pinmap_get(p->reg);
212 val &= ~(mask << shift);
213 val |= (v & mask) << shift;
214 pinmap_set(p->reg, val);
219 static int pin_switch_proc_show(struct seq_file *m, void *v)
222 struct sci_pin_switch *p = (struct sci_pin_switch *)(m->private);
223 val = read_write_pin_switch(1, (int)val, p);
224 seq_printf(m, "%d\n", val);
228 static int pin_switch_proc_open(struct inode *inode, struct file *file)
230 return single_open(file, pin_switch_proc_show, PDE_DATA(inode));
233 static ssize_t pin_switch_proc_write(struct file *file,
234 const char __user * buffer,
235 size_t count, loff_t * pos)
239 struct sci_pin_switch *p =
240 (struct sci_pin_switch *)(PDE_DATA(file_inode(file)));
241 ret = kstrtol_from_user(buffer, count, 0, &val);
243 pr_err("input err\n");
246 read_write_pin_switch(0, val, p);
250 static const struct file_operations pin_switch_fops = {
251 .open = pin_switch_proc_open,
254 .release = single_release,
255 .write = pin_switch_proc_write,
258 static int pin_switch_dir_proc_show(struct seq_file *m, void *v)
262 struct sci_pin_switch *p = (struct sci_pin_switch *)m->private;
263 func_tmp = read_write_pin_switch(1, val, p);
264 if (p->func == func_tmp)
268 seq_printf(m, "%d\n", val);
272 static int pin_switch_dir_proc_open(struct inode *inode, struct file *file)
274 return single_open(file, pin_switch_dir_proc_show, PDE_DATA(inode));
277 static ssize_t pin_switch_dir_proc_write(struct file *file,
278 const char __user * buffer,
279 size_t count, loff_t * pos)
283 struct sci_pin_switch *p =
284 (struct sci_pin_switch *)(PDE_DATA(file_inode(file)));
285 ret = kstrtol_from_user(buffer, count, 0, &val);
287 pr_err("input err\n");
292 else /*if val = 0 or other value, just ignore it */
294 read_write_pin_switch(0, val, p);
298 static const struct file_operations pin_switch_dir_fops = {
299 .open = pin_switch_dir_proc_open,
302 .release = single_release,
303 .write = pin_switch_dir_proc_write,
306 static struct proc_dir_entry *pin_switch_proc_base;
307 static int __init pin_switch_proc_add(struct sci_pin_switch *pin_switch)
309 struct proc_dir_entry *tmp_proc;
311 proc_create_data(pin_switch->filename, S_IRWXUGO,
312 pin_switch_proc_base, &pin_switch_fops,
319 static int __init pin_switch_proc_add_dir(struct sci_pin_switch_dir
322 struct proc_dir_entry *tmp_proc_dir;
323 struct proc_dir_entry *tmp_proc;
325 if (pin_switch_dir->sci_pin_switch->dirname == NULL)
327 /* has dir name, first create parent dir */
329 proc_mkdir(pin_switch_dir->sci_pin_switch->dirname,
330 pin_switch_proc_base);
334 for (i = 0; i < pin_switch_dir->array_size; ++i) {
335 if (pin_switch_dir->sci_pin_switch[i].filename == NULL)
338 proc_create_data(pin_switch_dir->sci_pin_switch[i].filename,
339 S_IRWXUGO, tmp_proc_dir,
340 &pin_switch_dir_fops,
341 &pin_switch_dir->sci_pin_switch[i]);
348 #if defined(CONFIG_PIN_POWER_DOMAIN_SWITCH)
349 static int sc271x_regulator_event(struct notifier_block *regu_nb,
350 unsigned long event, void *data)
353 struct pin_reg_desc *p_pin_reg_desc =
354 container_of(regu_nb, struct pin_reg_desc, nb);
355 unsigned long best_data = (unsigned long *)data;
356 const char *regu_name;
360 if (!p_pin_reg_desc) {
363 regu_name = p_pin_reg_desc->supplies.supply;
364 bit = p_pin_reg_desc->platform_data->bit_offset;
365 reg = p_pin_reg_desc->platform_data->reg;
366 pr_info("event:0x%x, best_data:0x%x\n", event, best_data);
368 if (event & REGULATOR_EVENT_VOLTAGE_CHANGE) {
369 if (p_pin_reg_desc) {
370 if (best_data > VOL_THRESHOLD) {
371 #if (defined(CONFIG_ARCH_SCX20L)||defined(CONFIG_ARCH_SCX20))
372 pinmap_set(reg, (pinmap_get(reg) | (1 << bit)));
374 pinmap_set(reg, (pinmap_get(reg) & ~(1 << bit)));
377 ("%s()->Line:%d, --REGULATOR_EVENT_VOLTAGE_CHANGE--> %s event %ld, data %ld\n",
378 __func__, __LINE__, regu_name, event,
381 #if (defined(CONFIG_ARCH_SCX20L)||defined(CONFIG_ARCH_SCX20))
382 pinmap_set(reg, (pinmap_get(reg) & ~(1 << bit)));
384 pinmap_set(reg, (pinmap_get(reg) | (1 << bit)));
387 ("%s()->Line:%d, --REGULATOR_EVENT_VOLTAGE_CHANGE--> %s event %ld, data %ld\n",
388 __func__, __LINE__, regu_name, event,
392 } else if (event & REGULATOR_EVENT_DISABLE) {
394 ("%s()->Line:%d, --REGULATOR_EVENT_DISABLE--> %s event %ld\n",
395 __func__, __LINE__, regu_name, event);
401 static int pin_regulator_notifier_register(struct pin_reg_desc *table)
404 struct regulator *regu;
406 for (i = 0; i < PD_CNT; i++) {
407 if (IS_ERR_OR_NULL(table[i].platform_data->power_domain)) {
408 pr_err("invalid platform data: 0x%p\n",
409 table[i].platform_data->power_domain);
413 regulator_get(NULL, table[i].platform_data->power_domain);
414 pr_info("%s, %d, regu_name:%s\n", __FUNCTION__, __LINE__,
415 table[i].platform_data->power_domain);
416 if (IS_ERR_OR_NULL(regu)) {
417 pr_err("no regu %s !\n",
418 table[i].platform_data->power_domain);
421 table[i].supplies.consumer = regu;
422 table[i].supplies.supply = table[i].platform_data->power_domain;
423 table[i].nb.notifier_call = sc271x_regulator_event;
424 ret = regulator_register_notifier(regu, &(table[i].nb));
426 pr_err("alert: regu %s reg notifier failed\n",
427 table[i].platform_data->power_domain);
433 static int sprd_pin_switch_probe(struct platform_device *pdev)
436 struct sprd_pin_switch_platform_data *p_pin_switch_data;
439 struct resource *res;
440 struct device_node *np = pdev->dev.of_node;
443 devm_kzalloc(&pdev->dev, sizeof(*p_pin_switch_data) * PD_CNT,
445 if (!p_pin_switch_data) {
446 pr_err("pin_switch alloc err\n");
450 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
452 dev_err(&pdev->dev, "No reg of property specified\n");
456 SPRD_PIN_BASE = (unsigned long)ioremap_nocache(res->start,res->end - res->start);
458 panic("pin_switch get address failed!\n");
461 pr_info("-----SPRD_PIN_BASE:0x%x-----\n", SPRD_PIN_BASE);
463 for (i = 0; i < PD_CNT; i++) {
464 /*1. get pin power domain vddname */
466 of_property_read_string_index(np, "pwr_domain", i,
467 &p_pin_switch_data[i].
470 pr_err("fail to get pwr_domain\n");
473 pr_info("pwr_domain[%d]:%s\n", i,
474 p_pin_switch_data[i].power_domain);
475 /*2. get pin power domain reg ctrl description info */
477 of_property_read_u32_index(np, "ctrl_desc", i * 3,
478 &p_pin_switch_data[i].reg);
480 pr_err("fail to get ctrl_desc reg\n");
483 pr_info("reg[%d]:0x%x\n", i, p_pin_switch_data[i].reg);
486 of_property_read_u32_index(np, "ctrl_desc", i * 3 + 1,
487 &p_pin_switch_data[i].
490 pr_err("fail to get ctrl_desc bit_offset\n");
493 pr_info("bit_offset[%d]:0x%x\n", i,
494 p_pin_switch_data[i].bit_offset);
496 of_property_read_u32_index(np, "ctrl_desc", i * 3 + 2,
497 &p_pin_switch_data[i].bit_width);
499 pr_err("fail to get ctrl_desc bit_width\n");
502 pr_info("bit_width[%d]:0x%x\n", i,
503 p_pin_switch_data[i].bit_width);
506 p_pin_switch_data = dev_get_platdata(&pdev->dev);
507 if (IS_ERR_OR_NULL(p_pin_switch_data)) {
508 pr_err("invalid platform data: 0x%p\n", p_pin_switch_data);
512 for (i = 0; i < PD_CNT; i++) {
513 pin_reg_desc_array[i].platform_data = &p_pin_switch_data[i]; // + i*sizeof(struct sprd_pin_switch_platform_data);
515 ret = pin_regulator_notifier_register(pin_reg_desc_array);
517 pr_err("register notifier err\n");
522 static struct of_device_id sprd_pinctrl_match_table[] = {
523 {.compatible = "sprd,pinctrl",},
527 static struct platform_driver pin_switch_driver = {
528 .probe = sprd_pin_switch_probe,
530 .owner = THIS_MODULE,
531 .name = "pin_switch",
532 .of_match_table = of_match_ptr(sprd_pinctrl_match_table),
537 int __init pin_switch_proc_init(void)
541 pin_switch_proc_base = proc_mkdir("pin_switch", NULL);
542 if (!pin_switch_proc_base)
544 for (i = 0; i < ARRAY_SIZE(sci_pin_switch_array); ++i) {
545 pin_switch_proc_add(&sci_pin_switch_array[i]);
547 for (i = 0; i < ARRAY_SIZE(sci_pin_switch_dir_array); ++i) {
548 pin_switch_proc_add_dir(&sci_pin_switch_dir_array[i]);
550 #if defined(CONFIG_PIN_POWER_DOMAIN_SWITCH)
551 ret = platform_driver_register(&pin_switch_driver);
556 subsys_initcall_sync(pin_switch_proc_init);
558 #error "CONFIG_PROC_FS needed by mach-sc/pin_switch"
559 #endif /* CONFIG_PROC_FS */