1
2
3
4
5
6
7
8
9
10#include <linux/clk.h>
11#include <linux/delay.h>
12#include <linux/gpio.h>
13#include <linux/interrupt.h>
14#include <linux/of_gpio.h>
15#include <linux/of_irq.h>
16#include <linux/module.h>
17#include <linux/pinctrl/consumer.h>
18#include <linux/platform_device.h>
19#include <linux/pm.h>
20#include <linux/regulator/consumer.h>
21#include <linux/spinlock.h>
22#include "arche_platform.h"
23
24
25struct arche_apb_ctrl_drvdata {
26
27 int resetn_gpio;
28 int boot_ret_gpio;
29 int pwroff_gpio;
30 int wake_in_gpio;
31 int wake_out_gpio;
32 int pwrdn_gpio;
33
34 enum arche_platform_state state;
35 bool init_disabled;
36
37 struct regulator *vcore;
38 struct regulator *vio;
39
40 int clk_en_gpio;
41 struct clk *clk;
42
43 struct pinctrl *pinctrl;
44 struct pinctrl_state *pin_default;
45
46
47 int spi_en_gpio;
48 bool spi_en_polarity_high;
49};
50
51
52
53
54static inline void deassert_reset(unsigned int gpio)
55{
56 gpio_set_value(gpio, 1);
57}
58
59static inline void assert_reset(unsigned int gpio)
60{
61 gpio_set_value(gpio, 0);
62}
63
64
65
66
67static int coldboot_seq(struct platform_device *pdev)
68{
69 struct device *dev = &pdev->dev;
70 struct arche_apb_ctrl_drvdata *apb = platform_get_drvdata(pdev);
71 int ret;
72
73 if (apb->init_disabled ||
74 apb->state == ARCHE_PLATFORM_STATE_ACTIVE)
75 return 0;
76
77
78 assert_reset(apb->resetn_gpio);
79
80 if (apb->state == ARCHE_PLATFORM_STATE_FW_FLASHING &&
81 gpio_is_valid(apb->spi_en_gpio))
82 devm_gpio_free(dev, apb->spi_en_gpio);
83
84
85 if (!IS_ERR(apb->vcore)) {
86 ret = regulator_enable(apb->vcore);
87 if (ret) {
88 dev_err(dev, "failed to enable core regulator\n");
89 return ret;
90 }
91 }
92
93 if (!IS_ERR(apb->vio)) {
94 ret = regulator_enable(apb->vio);
95 if (ret) {
96 dev_err(dev, "failed to enable IO regulator\n");
97 return ret;
98 }
99 }
100
101 apb_bootret_deassert(dev);
102
103
104 if (gpio_is_valid(apb->clk_en_gpio))
105 gpio_set_value(apb->clk_en_gpio, 1);
106
107 usleep_range(100, 200);
108
109
110 deassert_reset(apb->resetn_gpio);
111
112 apb->state = ARCHE_PLATFORM_STATE_ACTIVE;
113
114 return 0;
115}
116
117static int fw_flashing_seq(struct platform_device *pdev)
118{
119 struct device *dev = &pdev->dev;
120 struct arche_apb_ctrl_drvdata *apb = platform_get_drvdata(pdev);
121 int ret;
122
123 if (apb->init_disabled ||
124 apb->state == ARCHE_PLATFORM_STATE_FW_FLASHING)
125 return 0;
126
127 ret = regulator_enable(apb->vcore);
128 if (ret) {
129 dev_err(dev, "failed to enable core regulator\n");
130 return ret;
131 }
132
133 ret = regulator_enable(apb->vio);
134 if (ret) {
135 dev_err(dev, "failed to enable IO regulator\n");
136 return ret;
137 }
138
139 if (gpio_is_valid(apb->spi_en_gpio)) {
140 unsigned long flags;
141
142 if (apb->spi_en_polarity_high)
143 flags = GPIOF_OUT_INIT_HIGH;
144 else
145 flags = GPIOF_OUT_INIT_LOW;
146
147 ret = devm_gpio_request_one(dev, apb->spi_en_gpio,
148 flags, "apb_spi_en");
149 if (ret) {
150 dev_err(dev, "Failed requesting SPI bus en gpio %d\n",
151 apb->spi_en_gpio);
152 return ret;
153 }
154 }
155
156
157 assert_reset(apb->resetn_gpio);
158 apb->state = ARCHE_PLATFORM_STATE_FW_FLASHING;
159
160 return 0;
161}
162
163static int standby_boot_seq(struct platform_device *pdev)
164{
165 struct device *dev = &pdev->dev;
166 struct arche_apb_ctrl_drvdata *apb = platform_get_drvdata(pdev);
167
168 if (apb->init_disabled)
169 return 0;
170
171
172 if (apb->state == ARCHE_PLATFORM_STATE_STANDBY ||
173 apb->state == ARCHE_PLATFORM_STATE_OFF)
174 return 0;
175
176 if (apb->state == ARCHE_PLATFORM_STATE_FW_FLASHING &&
177 gpio_is_valid(apb->spi_en_gpio))
178 devm_gpio_free(dev, apb->spi_en_gpio);
179
180
181
182
183
184
185
186
187
188
189 apb->state = ARCHE_PLATFORM_STATE_STANDBY;
190 return 0;
191}
192
193static void poweroff_seq(struct platform_device *pdev)
194{
195 struct device *dev = &pdev->dev;
196 struct arche_apb_ctrl_drvdata *apb = platform_get_drvdata(pdev);
197
198 if (apb->init_disabled || apb->state == ARCHE_PLATFORM_STATE_OFF)
199 return;
200
201 if (apb->state == ARCHE_PLATFORM_STATE_FW_FLASHING &&
202 gpio_is_valid(apb->spi_en_gpio))
203 devm_gpio_free(dev, apb->spi_en_gpio);
204
205
206 if (gpio_is_valid(apb->clk_en_gpio))
207 gpio_set_value(apb->clk_en_gpio, 0);
208
209 if (!IS_ERR(apb->vcore) && regulator_is_enabled(apb->vcore) > 0)
210 regulator_disable(apb->vcore);
211
212 if (!IS_ERR(apb->vio) && regulator_is_enabled(apb->vio) > 0)
213 regulator_disable(apb->vio);
214
215
216 assert_reset(apb->resetn_gpio);
217 apb->state = ARCHE_PLATFORM_STATE_OFF;
218
219
220}
221
222void apb_bootret_assert(struct device *dev)
223{
224 struct arche_apb_ctrl_drvdata *apb = dev_get_drvdata(dev);
225
226 gpio_set_value(apb->boot_ret_gpio, 1);
227}
228
229void apb_bootret_deassert(struct device *dev)
230{
231 struct arche_apb_ctrl_drvdata *apb = dev_get_drvdata(dev);
232
233 gpio_set_value(apb->boot_ret_gpio, 0);
234}
235
236int apb_ctrl_coldboot(struct device *dev)
237{
238 return coldboot_seq(to_platform_device(dev));
239}
240
241int apb_ctrl_fw_flashing(struct device *dev)
242{
243 return fw_flashing_seq(to_platform_device(dev));
244}
245
246int apb_ctrl_standby_boot(struct device *dev)
247{
248 return standby_boot_seq(to_platform_device(dev));
249}
250
251void apb_ctrl_poweroff(struct device *dev)
252{
253 poweroff_seq(to_platform_device(dev));
254}
255
256static ssize_t state_store(struct device *dev,
257 struct device_attribute *attr, const char *buf, size_t count)
258{
259 struct platform_device *pdev = to_platform_device(dev);
260 struct arche_apb_ctrl_drvdata *apb = platform_get_drvdata(pdev);
261 int ret = 0;
262 bool is_disabled;
263
264 if (sysfs_streq(buf, "off")) {
265 if (apb->state == ARCHE_PLATFORM_STATE_OFF)
266 return count;
267
268 poweroff_seq(pdev);
269 } else if (sysfs_streq(buf, "active")) {
270 if (apb->state == ARCHE_PLATFORM_STATE_ACTIVE)
271 return count;
272
273 poweroff_seq(pdev);
274 is_disabled = apb->init_disabled;
275 apb->init_disabled = false;
276 ret = coldboot_seq(pdev);
277 if (ret)
278 apb->init_disabled = is_disabled;
279 } else if (sysfs_streq(buf, "standby")) {
280 if (apb->state == ARCHE_PLATFORM_STATE_STANDBY)
281 return count;
282
283 ret = standby_boot_seq(pdev);
284 } else if (sysfs_streq(buf, "fw_flashing")) {
285 if (apb->state == ARCHE_PLATFORM_STATE_FW_FLASHING)
286 return count;
287
288
289
290 poweroff_seq(pdev);
291 ret = fw_flashing_seq(pdev);
292 } else {
293 dev_err(dev, "unknown state\n");
294 ret = -EINVAL;
295 }
296
297 return ret ? ret : count;
298}
299
300static ssize_t state_show(struct device *dev,
301 struct device_attribute *attr, char *buf)
302{
303 struct arche_apb_ctrl_drvdata *apb = dev_get_drvdata(dev);
304
305 switch (apb->state) {
306 case ARCHE_PLATFORM_STATE_OFF:
307 return sprintf(buf, "off%s\n",
308 apb->init_disabled ? ",disabled" : "");
309 case ARCHE_PLATFORM_STATE_ACTIVE:
310 return sprintf(buf, "active\n");
311 case ARCHE_PLATFORM_STATE_STANDBY:
312 return sprintf(buf, "standby\n");
313 case ARCHE_PLATFORM_STATE_FW_FLASHING:
314 return sprintf(buf, "fw_flashing\n");
315 default:
316 return sprintf(buf, "unknown state\n");
317 }
318}
319
320static DEVICE_ATTR_RW(state);
321
322static int apb_ctrl_get_devtree_data(struct platform_device *pdev,
323 struct arche_apb_ctrl_drvdata *apb)
324{
325 struct device *dev = &pdev->dev;
326 struct device_node *np = dev->of_node;
327 int ret;
328
329 apb->resetn_gpio = of_get_named_gpio(np, "reset-gpios", 0);
330 if (apb->resetn_gpio < 0) {
331 dev_err(dev, "failed to get reset gpio\n");
332 return apb->resetn_gpio;
333 }
334 ret = devm_gpio_request_one(dev, apb->resetn_gpio,
335 GPIOF_OUT_INIT_LOW, "apb-reset");
336 if (ret) {
337 dev_err(dev, "Failed requesting reset gpio %d\n",
338 apb->resetn_gpio);
339 return ret;
340 }
341
342 apb->boot_ret_gpio = of_get_named_gpio(np, "boot-ret-gpios", 0);
343 if (apb->boot_ret_gpio < 0) {
344 dev_err(dev, "failed to get boot retention gpio\n");
345 return apb->boot_ret_gpio;
346 }
347 ret = devm_gpio_request_one(dev, apb->boot_ret_gpio,
348 GPIOF_OUT_INIT_LOW, "boot retention");
349 if (ret) {
350 dev_err(dev, "Failed requesting bootret gpio %d\n",
351 apb->boot_ret_gpio);
352 return ret;
353 }
354
355
356 apb->pwroff_gpio = of_get_named_gpio(np, "pwr-off-gpios", 0);
357 if (apb->pwroff_gpio < 0) {
358 dev_err(dev, "failed to get power off gpio\n");
359 return apb->pwroff_gpio;
360 }
361 ret = devm_gpio_request_one(dev, apb->pwroff_gpio,
362 GPIOF_IN, "pwroff_n");
363 if (ret) {
364 dev_err(dev, "Failed requesting pwroff_n gpio %d\n",
365 apb->pwroff_gpio);
366 return ret;
367 }
368
369
370 apb->clk_en_gpio = of_get_named_gpio(np, "clock-en-gpio", 0);
371 if (apb->clk_en_gpio < 0) {
372 dev_warn(dev, "failed to get clock en gpio\n");
373 } else if (gpio_is_valid(apb->clk_en_gpio)) {
374 ret = devm_gpio_request_one(dev, apb->clk_en_gpio,
375 GPIOF_OUT_INIT_LOW, "apb_clk_en");
376 if (ret) {
377 dev_warn(dev, "Failed requesting APB clock en gpio %d\n",
378 apb->clk_en_gpio);
379 return ret;
380 }
381 }
382
383 apb->pwrdn_gpio = of_get_named_gpio(np, "pwr-down-gpios", 0);
384 if (apb->pwrdn_gpio < 0)
385 dev_warn(dev, "failed to get power down gpio\n");
386
387
388 apb->vcore = devm_regulator_get(dev, "vcore");
389 if (IS_ERR(apb->vcore))
390 dev_warn(dev, "no core regulator found\n");
391
392 apb->vio = devm_regulator_get(dev, "vio");
393 if (IS_ERR(apb->vio))
394 dev_warn(dev, "no IO regulator found\n");
395
396 apb->pinctrl = devm_pinctrl_get(&pdev->dev);
397 if (IS_ERR(apb->pinctrl)) {
398 dev_err(&pdev->dev, "could not get pinctrl handle\n");
399 return PTR_ERR(apb->pinctrl);
400 }
401 apb->pin_default = pinctrl_lookup_state(apb->pinctrl, "default");
402 if (IS_ERR(apb->pin_default)) {
403 dev_err(&pdev->dev, "could not get default pin state\n");
404 return PTR_ERR(apb->pin_default);
405 }
406
407
408 apb->spi_en_gpio = of_get_named_gpio(np, "spi-en-gpio", 0);
409 if (apb->spi_en_gpio >= 0) {
410 if (of_property_read_bool(pdev->dev.of_node,
411 "spi-en-active-high"))
412 apb->spi_en_polarity_high = true;
413 }
414
415 return 0;
416}
417
418static int arche_apb_ctrl_probe(struct platform_device *pdev)
419{
420 int ret;
421 struct arche_apb_ctrl_drvdata *apb;
422 struct device *dev = &pdev->dev;
423
424 apb = devm_kzalloc(&pdev->dev, sizeof(*apb), GFP_KERNEL);
425 if (!apb)
426 return -ENOMEM;
427
428 ret = apb_ctrl_get_devtree_data(pdev, apb);
429 if (ret) {
430 dev_err(dev, "failed to get apb devicetree data %d\n", ret);
431 return ret;
432 }
433
434
435 apb->state = ARCHE_PLATFORM_STATE_OFF;
436
437 if (of_property_read_bool(pdev->dev.of_node, "arche,init-disable"))
438 apb->init_disabled = true;
439
440 platform_set_drvdata(pdev, apb);
441
442
443 ret = device_create_file(dev, &dev_attr_state);
444 if (ret) {
445 dev_err(dev, "failed to create state file in sysfs\n");
446 return ret;
447 }
448
449 dev_info(&pdev->dev, "Device registered successfully\n");
450 return 0;
451}
452
453static int arche_apb_ctrl_remove(struct platform_device *pdev)
454{
455 device_remove_file(&pdev->dev, &dev_attr_state);
456 poweroff_seq(pdev);
457 platform_set_drvdata(pdev, NULL);
458
459 return 0;
460}
461
462static int arche_apb_ctrl_suspend(struct device *dev)
463{
464
465
466
467
468
469
470
471
472
473 return 0;
474}
475
476static int arche_apb_ctrl_resume(struct device *dev)
477{
478
479
480
481
482
483
484
485
486
487 return 0;
488}
489
490static void arche_apb_ctrl_shutdown(struct platform_device *pdev)
491{
492 apb_ctrl_poweroff(&pdev->dev);
493}
494
495static SIMPLE_DEV_PM_OPS(arche_apb_ctrl_pm_ops, arche_apb_ctrl_suspend,
496 arche_apb_ctrl_resume);
497
498static const struct of_device_id arche_apb_ctrl_of_match[] = {
499 { .compatible = "usbffff,2", },
500 { },
501};
502
503static struct platform_driver arche_apb_ctrl_device_driver = {
504 .probe = arche_apb_ctrl_probe,
505 .remove = arche_apb_ctrl_remove,
506 .shutdown = arche_apb_ctrl_shutdown,
507 .driver = {
508 .name = "arche-apb-ctrl",
509 .pm = &arche_apb_ctrl_pm_ops,
510 .of_match_table = arche_apb_ctrl_of_match,
511 }
512};
513
514int __init arche_apb_init(void)
515{
516 return platform_driver_register(&arche_apb_ctrl_device_driver);
517}
518
519void __exit arche_apb_exit(void)
520{
521 platform_driver_unregister(&arche_apb_ctrl_device_driver);
522}
523