1c3d0bd19bf6676d5ce82b8726f690919025c5cf
[profile/mobile/platform/kernel/linux-3.10-sc7730.git] / drivers / platform / sprd / pin_switch.c
1 //      #define DEBUG
2 //      #define pr_fmt(fmt) "---sprd pinswitch---"fmt
3
4 #include <linux/io.h>
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>
13 #include <linux/of.h>
14 #include <soc/sprd/pin_switch.h>
15 #include <linux/regulator/consumer.h>
16
17 #ifdef CONFIG_PROC_FS
18
19 #undef SPRD_PIN_BASE
20 unsigned long SPRD_PIN_BASE = 0;
21 struct sci_pin_switch {
22         const char *dirname;
23         const char *filename;
24         u32 reg;
25         u32 bit_offset;
26         u32 bit_width;
27         u32 func;
28 };
29
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},
51 #endif
52 #endif
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},
59 };
60
61
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},
69 };
70
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},
77 };
78
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},
85 };
86
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},
93 };
94 #else
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},
112 };
113
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},
120 };
121
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},
127 };
128
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},
135 };
136
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},
142 };
143 #endif
144 #endif
145
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];
152 #endif
153
154 static struct sci_pin_switch_dir {
155         struct sci_pin_switch *sci_pin_switch;
156         u32 array_size;
157 } sci_pin_switch_dir_array[] = {
158 #if !defined(CONFIG_ARCH_SCX35L)
159         {
160         bt_iis_sys_sel_array, ARRAY_SIZE(bt_iis_sys_sel_array)},
161 #endif
162         {
163         iis_0_array, ARRAY_SIZE(iis_0_array)}, {
164         iis_1_array, ARRAY_SIZE(iis_1_array)},
165 #if !defined(CONFIG_ARCH_SCX15)
166         {
167         iis_2_array, ARRAY_SIZE(iis_2_array)}, {
168         iis_3_array, ARRAY_SIZE(iis_3_array)},
169 #endif
170 };
171
172 u32 pinmap_get(u32 offset)
173 {
174         return readl(SPRD_PIN_BASE + offset);
175 }
176
177 EXPORT_SYMBOL(pinmap_get);
178 int pinmap_set(u32 offset, u32 value)
179 {
180         unsigned long flags;
181         __arch_default_lock(HWLOCK_GLB, &flags);
182         writel(value, SPRD_PIN_BASE + offset);
183         __arch_default_unlock(HWLOCK_GLB, &flags);
184         return 0;
185 }
186
187 EXPORT_SYMBOL(pinmap_set);
188
189 /*
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)
195 */
196 static int read_write_pin_switch(int is_read, int v, struct sci_pin_switch *p)
197 {
198         int val = 0;
199         u32 shift = p->bit_offset;
200         u32 mask = (1 << (p->bit_width)) - 1;
201         if ((shift > 31))
202                 BUG_ON(1);
203         if (v > mask)
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);
207         if (is_read) {
208                 val >>= shift;
209                 val &= mask;
210                 return val;
211         } else {
212                 val &= ~(mask << shift);
213                 val |= (v & mask) << shift;
214                 pinmap_set(p->reg, val);
215         }
216         return val;
217 }
218
219 static int pin_switch_proc_show(struct seq_file *m, void *v)
220 {
221         int val = 0;
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);
225         return 0;
226 }
227
228 static int pin_switch_proc_open(struct inode *inode, struct file *file)
229 {
230         return single_open(file, pin_switch_proc_show, PDE_DATA(inode));
231 }
232
233 static ssize_t pin_switch_proc_write(struct file *file,
234                                      const char __user * buffer,
235                                      size_t count, loff_t * pos)
236 {
237         long val = 0;
238         int ret = 0;
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);
242         if (ret) {
243                 pr_err("input err\n");
244                 return -EINVAL;
245         }
246         read_write_pin_switch(0, val, p);
247         return count;
248 }
249
250 static const struct file_operations pin_switch_fops = {
251         .open = pin_switch_proc_open,
252         .read = seq_read,
253         .llseek = seq_lseek,
254         .release = single_release,
255         .write = pin_switch_proc_write,
256 };
257
258 static int pin_switch_dir_proc_show(struct seq_file *m, void *v)
259 {
260         int val = 0;
261         int func_tmp = 0;
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)
265                 val = 1;
266         else
267                 val = 0;
268         seq_printf(m, "%d\n", val);
269         return 0;
270 }
271
272 static int pin_switch_dir_proc_open(struct inode *inode, struct file *file)
273 {
274         return single_open(file, pin_switch_dir_proc_show, PDE_DATA(inode));
275 }
276
277 static ssize_t pin_switch_dir_proc_write(struct file *file,
278                                          const char __user * buffer,
279                                          size_t count, loff_t * pos)
280 {
281         int val = 0;
282         int ret = 0;
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);
286         if (ret) {
287                 pr_err("input err\n");
288                 return -EINVAL;
289         }
290         if (val == 1)
291                 val = p->func;
292         else                    /*if val = 0 or other value, just ignore it */
293                 return 0;
294         read_write_pin_switch(0, val, p);
295         return count;
296 }
297
298 static const struct file_operations pin_switch_dir_fops = {
299         .open = pin_switch_dir_proc_open,
300         .read = seq_read,
301         .llseek = seq_lseek,
302         .release = single_release,
303         .write = pin_switch_dir_proc_write,
304 };
305
306 static struct proc_dir_entry *pin_switch_proc_base;
307 static int __init pin_switch_proc_add(struct sci_pin_switch *pin_switch)
308 {
309         struct proc_dir_entry *tmp_proc;
310         tmp_proc =
311             proc_create_data(pin_switch->filename, S_IRWXUGO,
312                              pin_switch_proc_base, &pin_switch_fops,
313                              pin_switch);
314         if (!tmp_proc)
315                 return -ENOMEM;
316         return 0;
317 }
318
319 static int __init pin_switch_proc_add_dir(struct sci_pin_switch_dir
320                                           *pin_switch_dir)
321 {
322         struct proc_dir_entry *tmp_proc_dir;
323         struct proc_dir_entry *tmp_proc;
324         int i;
325         if (pin_switch_dir->sci_pin_switch->dirname == NULL)
326                 return EINVAL;
327         /* has dir name, first create parent dir */
328         tmp_proc_dir =
329             proc_mkdir(pin_switch_dir->sci_pin_switch->dirname,
330                        pin_switch_proc_base);
331         if (!tmp_proc_dir)
332                 return -ENOMEM;
333
334         for (i = 0; i < pin_switch_dir->array_size; ++i) {
335                 if (pin_switch_dir->sci_pin_switch[i].filename == NULL)
336                         return EINVAL;
337                 tmp_proc =
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]);
342                 if (!tmp_proc)
343                         return -EINVAL;
344         }
345         return 0;
346 }
347
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)
351 {
352         unsigned long flags;
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;
357         u32 bit;
358         u32 reg;
359
360         if (!p_pin_reg_desc) {
361                 return -EINVAL;
362         }
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);
367
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)));
373                                 #else
374                                         pinmap_set(reg, (pinmap_get(reg) & ~(1 << bit)));
375                                 #endif
376                                         pr_info
377                                                 ("%s()->Line:%d, --REGULATOR_EVENT_VOLTAGE_CHANGE--> %s event %ld, data %ld\n",
378                                                 __func__, __LINE__, regu_name, event,
379                                                 best_data);
380                         } else {
381                                 #if (defined(CONFIG_ARCH_SCX20L)||defined(CONFIG_ARCH_SCX20))
382                                         pinmap_set(reg, (pinmap_get(reg) & ~(1 << bit)));
383                                 #else
384                                         pinmap_set(reg, (pinmap_get(reg) | (1 << bit)));
385                                 #endif
386                                         pr_info
387                                                 ("%s()->Line:%d, --REGULATOR_EVENT_VOLTAGE_CHANGE--> %s event %ld, data %ld\n",
388                                                 __func__, __LINE__, regu_name, event,
389                                                 best_data);
390                         }
391                 }
392         } else if (event & REGULATOR_EVENT_DISABLE) {
393                 pr_info
394                     ("%s()->Line:%d, --REGULATOR_EVENT_DISABLE--> %s event %ld\n",
395                      __func__, __LINE__, regu_name, event);
396         }
397
398         return NOTIFY_OK;
399 }
400
401 static int pin_regulator_notifier_register(struct pin_reg_desc *table)
402 {
403         int i, ret;
404         struct regulator *regu;
405
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);
410                         return -EINVAL;
411                 }
412                 regu =
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);
419                         return -ENXIO;;
420                 }
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));
425                 if (ret) {
426                         pr_err("alert: regu %s reg notifier failed\n",
427                                table[i].platform_data->power_domain);
428                 }
429         }
430         return 0;
431 }
432
433 static int sprd_pin_switch_probe(struct platform_device *pdev)
434 {
435         int i, ret;
436         struct sprd_pin_switch_platform_data *p_pin_switch_data;
437
438 #ifdef CONFIG_OF
439         struct resource *res;
440         struct device_node *np = pdev->dev.of_node;
441
442         p_pin_switch_data =
443             devm_kzalloc(&pdev->dev, sizeof(*p_pin_switch_data) * PD_CNT,
444                          GFP_KERNEL);
445         if (!p_pin_switch_data) {
446                 pr_err("pin_switch alloc err\n");
447                 return -ENOMEM;
448         }
449
450         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
451         if (!res) {
452                 dev_err(&pdev->dev, "No reg of property specified\n");
453                 return -ENODEV;
454         }
455
456         SPRD_PIN_BASE = (unsigned long)ioremap_nocache(res->start,res->end - res->start);
457                 if (!SPRD_PIN_BASE)
458                         panic("pin_switch get address failed!\n");
459
460
461         pr_info("-----SPRD_PIN_BASE:0x%x-----\n", SPRD_PIN_BASE);
462
463         for (i = 0; i < PD_CNT; i++) {
464                 /*1. get pin power domain vddname */
465                 ret =
466                     of_property_read_string_index(np, "pwr_domain", i,
467                                                   &p_pin_switch_data[i].
468                                                   power_domain);
469                 if (ret) {
470                         pr_err("fail to get pwr_domain\n");
471                         return ret;
472                 }
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 */
476                 ret =
477                     of_property_read_u32_index(np, "ctrl_desc", i * 3,
478                                                &p_pin_switch_data[i].reg);
479                 if (ret) {
480                         pr_err("fail to get ctrl_desc reg\n");
481                         return ret;
482                 }
483                 pr_info("reg[%d]:0x%x\n", i, p_pin_switch_data[i].reg);
484
485                 ret =
486                     of_property_read_u32_index(np, "ctrl_desc", i * 3 + 1,
487                                                &p_pin_switch_data[i].
488                                                bit_offset);
489                 if (ret) {
490                         pr_err("fail to get ctrl_desc bit_offset\n");
491                         return ret;
492                 }
493                 pr_info("bit_offset[%d]:0x%x\n", i,
494                         p_pin_switch_data[i].bit_offset);
495                 ret =
496                     of_property_read_u32_index(np, "ctrl_desc", i * 3 + 2,
497                                                &p_pin_switch_data[i].bit_width);
498                 if (ret) {
499                         pr_err("fail to get ctrl_desc bit_width\n");
500                         return ret;
501                 }
502                 pr_info("bit_width[%d]:0x%x\n", i,
503                         p_pin_switch_data[i].bit_width);
504         }
505 #else
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);
509                 return -EINVAL;
510         }
511 #endif
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);
514         }
515         ret = pin_regulator_notifier_register(pin_reg_desc_array);
516         if (ret) {
517                 pr_err("register notifier err\n");
518         }
519         return ret;
520 }
521
522 static struct of_device_id sprd_pinctrl_match_table[] = {
523         {.compatible = "sprd,pinctrl",},
524         {},
525 };
526
527 static struct platform_driver pin_switch_driver = {
528         .probe = sprd_pin_switch_probe,
529         .driver = {
530                    .owner = THIS_MODULE,
531                    .name = "pin_switch",
532                    .of_match_table = of_match_ptr(sprd_pinctrl_match_table),
533                    },
534 };
535 #endif
536
537 int __init pin_switch_proc_init(void)
538 {
539         int i;
540         int ret = 0;
541         pin_switch_proc_base = proc_mkdir("pin_switch", NULL);
542         if (!pin_switch_proc_base)
543                 return -ENOMEM;
544         for (i = 0; i < ARRAY_SIZE(sci_pin_switch_array); ++i) {
545                 pin_switch_proc_add(&sci_pin_switch_array[i]);
546         }
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]);
549         }
550 #if defined(CONFIG_PIN_POWER_DOMAIN_SWITCH)
551         ret = platform_driver_register(&pin_switch_driver);
552 #endif
553         return ret;
554 }
555
556 subsys_initcall_sync(pin_switch_proc_init);
557 #else
558 #error "CONFIG_PROC_FS needed by mach-sc/pin_switch"
559 #endif /* CONFIG_PROC_FS */