· 9 years ago · Jan 14, 2017, 09:04 PM
1diff -urN target.orig/linux/x86/64/profiles/001-pcengines.mk target/linux/x86/64/profiles/001-pcengines.mk
2--- target.orig/linux/x86/64/profiles/001-pcengines.mk 1969-12-31 19:00:00.000000000 -0500
3+++ target/linux/x86/64/profiles/001-pcengines.mk 2016-08-18 15:21:15.404178300 -0400
4@@ -0,0 +1,38 @@
5+#
6+# Copyright (C) 2016 Chris Blake <chrisrblake93 at gmail.com>
7+#
8+# This is free software, licensed under the GNU General Public License v2.
9+# See /LICENSE for more information.
10+#
11+
12+define Profile/APU
13+ NAME:=PC Engines APU
14+ PACKAGES:=kmod-r8169 hwclock kmod-button-hotplug \
15+ kmod-i2c-core kmod-i2c-piix4 \
16+ kmod-usb-core kmod-usb-ohci kmod-usb2 kmod-usb3 \
17+ kmod-hwmon-core kmod-hwmon-k10temp libsensors lm-sensors kmod-sp5100_tco \
18+ kmod-sound-core kmod-pcspkr \
19+ kmod-leds-apu kmod-ledtrig-heartbeat kmod-ledtrig-gpio kmod-ledtrig-netdev
20+endef
21+
22+define Profile/APU/Description
23+ PC Engines APU Embedded Board
24+endef
25+$(eval $(call Profile,APU))
26+
27+
28+define Profile/APU2
29+ NAME:=PC Engines APU2
30+ PACKAGES:=kmod-igb hwclock kmod-button-hotplug \
31+ kmod-i2c-core kmod-i2c-piix4 \
32+ kmod-usb-core kmod-usb-ohci kmod-usb2 kmod-usb3 \
33+ kmod-hwmon-core kmod-hwmon-k10temp libsensors lm-sensors kmod-sp5100_tco \
34+ kmod-sound-core kmod-pcspkr \
35+ kmod-leds-apu2 kmod-ledtrig-heartbeat kmod-ledtrig-gpio kmod-ledtrig-netdev
36+endef
37+
38+define Profile/APU2/Description
39+ PC Engines APU2 Embedded Board
40+endef
41+$(eval $(call Profile,APU2))
42+
43diff -urN target.old/linux/generic/files/drivers/leds/leds-apu.c target/linux/generic/files/drivers/leds/leds-apu.c
44--- target.old/linux/generic/files/drivers/leds/leds-apu.c 1969-12-31 19:00:00.000000000 -0500
45+++ target/linux/generic/files/drivers/leds/leds-apu.c 2016-08-19 09:14:56.892178300 -0400
46@@ -0,0 +1,234 @@
47+/*
48+ * LEDs driver for PCEngines apu
49+ *
50+ * Copyright (C) 2013 Christian Herzog <daduke@daduke.org>, based on
51+ * Petr Leibman's leds-alix
52+ * Based on leds-wrap.c
53+ * Hardware info taken from http://www.dpie.com/manuals/miniboards/kontron/KTD-S0043-0_KTA55_SoftwareGuide.pdf
54+ *
55+ * 2014-12-8: Mark Schank
56+ * - Added GPIO support for the APU push-button switch.
57+ *
58+ * This program is free software; you can redistribute it and/or modify
59+ * it under the terms of the GNU General Public License version 2 as
60+ * published by the Free Software Foundation.
61+ */
62+#define APU_BUTTON // Enable gpio support for the APU button switch
63+
64+#include <linux/kernel.h>
65+#include <linux/module.h>
66+#include <linux/init.h>
67+#include <linux/platform_device.h>
68+#include <linux/leds.h>
69+#ifdef APU_BUTTON
70+#include <linux/gpio.h>
71+#endif
72+#include <linux/err.h>
73+#include <asm/io.h>
74+
75+#define DRVNAME "apu-led"
76+#define BASEADDR (0xFED801BD)
77+#define LEDON (0x8)
78+#define LEDOFF (0xC8)
79+
80+static struct platform_device *pdev;
81+unsigned int *p1;
82+unsigned int *p2;
83+unsigned int *p3;
84+
85+#ifdef APU_BUTTON
86+#define BUTTONADDR (0xFED801BB)
87+unsigned int *b1;
88+#endif
89+
90+static void apu_led_set_1(struct led_classdev *led_cdev,
91+ enum led_brightness value) {
92+ if (value)
93+ iowrite8(LEDON, p1);
94+ else
95+ iowrite8(LEDOFF, p1);
96+}
97+
98+static void apu_led_set_2(struct led_classdev *led_cdev,
99+ enum led_brightness value) {
100+ if (value)
101+ iowrite8(LEDON, p2);
102+ else
103+ iowrite8(LEDOFF, p2);
104+}
105+
106+static void apu_led_set_3(struct led_classdev *led_cdev,
107+ enum led_brightness value) {
108+ if (value)
109+ iowrite8(LEDON, p3);
110+ else
111+ iowrite8(LEDOFF, p3);
112+}
113+
114+static struct led_classdev apu_led_1 = {
115+ .name = "apu:1",
116+ .brightness_set = apu_led_set_1,
117+};
118+
119+static struct led_classdev apu_led_2 = {
120+ .name = "apu:2",
121+ .brightness_set = apu_led_set_2,
122+};
123+
124+static struct led_classdev apu_led_3 = {
125+ .name = "apu:3",
126+ .brightness_set = apu_led_set_3,
127+};
128+
129+#ifdef APU_BUTTON
130+static int gpio_apu_button_direction_in(struct gpio_chip *gc, unsigned gpio_num)
131+{
132+ u8 curr_state;
133+
134+ curr_state = ioread8(b1);
135+ iowrite8(curr_state | (1 << 5), b1);
136+
137+ return 0;
138+}
139+
140+static int gpio_apu_button_get(struct gpio_chip *gc, unsigned gpio_num)
141+{
142+ u8 curr_state;
143+
144+ curr_state = ioread8(b1);
145+
146+ return((curr_state & (1 << 7)) == (1 << 7));
147+}
148+
149+static struct gpio_chip apu_gpio_button = {
150+ .label = "apu_button",
151+ .owner = THIS_MODULE,
152+ .get = gpio_apu_button_get,
153+ .direction_input = gpio_apu_button_direction_in,
154+ .base = 187,
155+ .ngpio = 1,
156+};
157+#endif
158+
159+
160+#ifdef CONFIG_PM
161+static int apu_led_suspend(struct platform_device *dev,
162+ pm_message_t state)
163+{
164+ led_classdev_suspend(&apu_led_1);
165+ led_classdev_suspend(&apu_led_2);
166+ led_classdev_suspend(&apu_led_3);
167+ return 0;
168+}
169+
170+static int apu_led_resume(struct platform_device *dev)
171+{
172+ led_classdev_resume(&apu_led_1);
173+ led_classdev_resume(&apu_led_2);
174+ led_classdev_resume(&apu_led_3);
175+ return 0;
176+}
177+#else
178+#define apu_led_suspend NULL
179+#define apu_led_resume NULL
180+#endif
181+
182+static int apu_led_probe(struct platform_device *pdev)
183+{
184+ int ret;
185+
186+ ret = led_classdev_register(&pdev->dev, &apu_led_1);
187+ if (ret == 0)
188+ {
189+ ret = led_classdev_register(&pdev->dev, &apu_led_2);
190+ if (ret >= 0)
191+ {
192+ ret = led_classdev_register(&pdev->dev, &apu_led_3);
193+ if (ret >= 0)
194+ {
195+#ifdef APU_BUTTON
196+ ret = gpiochip_add(&apu_gpio_button);
197+ if(ret == 0){
198+ if(!gpio_request_one(187, GPIOF_IN, "Button")){
199+ gpio_export(187, 0);
200+ }
201+ }
202+ if (ret < 0)
203+ led_classdev_unregister(&apu_led_3);
204+#endif
205+ }
206+ if (ret < 0)
207+ led_classdev_unregister(&apu_led_2);
208+ }
209+ if (ret < 0)
210+ led_classdev_unregister(&apu_led_1);
211+ }
212+ return ret;
213+}
214+
215+static int apu_led_remove(struct platform_device *pdev)
216+{
217+#ifdef APU_BUTTON
218+ int ret;
219+#endif
220+ led_classdev_unregister(&apu_led_1);
221+ led_classdev_unregister(&apu_led_2);
222+ led_classdev_unregister(&apu_led_3);
223+
224+#ifdef APU_BUTTON
225+ gpiochip_remove(&apu_gpio_button);
226+#else
227+ return 0;
228+#endif
229+}
230+
231+static struct platform_driver apu_led_driver = {
232+ .probe = apu_led_probe,
233+ .remove = apu_led_remove,
234+ .suspend = apu_led_suspend,
235+ .resume = apu_led_resume,
236+ .driver = {
237+ .name = DRVNAME,
238+ .owner = THIS_MODULE,
239+ },
240+};
241+
242+static int __init apu_led_init(void)
243+{
244+ int ret;
245+
246+#ifdef APU_BUTTON
247+ b1 = ioremap(BUTTONADDR, 1);
248+#endif
249+
250+ ret = platform_driver_register(&apu_led_driver);
251+ if (ret < 0)
252+ goto out;
253+
254+ pdev = platform_device_register_simple(DRVNAME, -1, NULL, 0);
255+ if (IS_ERR(pdev)) {
256+ ret = PTR_ERR(pdev);
257+ platform_driver_unregister(&apu_led_driver);
258+ goto out;
259+ }
260+
261+ p1 = ioremap(BASEADDR, 1);
262+ p2 = ioremap(BASEADDR+1, 1);
263+ p3 = ioremap(BASEADDR+2, 1);
264+
265+out:
266+ return ret;
267+}
268+
269+static void __exit apu_led_exit(void)
270+{
271+ platform_device_unregister(pdev);
272+ platform_driver_unregister(&apu_led_driver);
273+}
274+
275+module_init(apu_led_init);
276+module_exit(apu_led_exit);
277+
278+MODULE_AUTHOR("Christian Herzog");
279+MODULE_DESCRIPTION("PCEngines apu LED driver");
280+MODULE_LICENSE("GPL");
281diff -urN target.old/linux/x86/64/config-default target/linux/x86/64/config-default
282--- target.old/linux/x86/64/config-default 2016-08-19 12:16:43.040178300 -0400
283+++ target/linux/x86/64/config-default 2016-08-19 12:26:05.732178300 -0400
284@@ -261,3 +261,23 @@
285 # CONFIG_X86_X32 is not set
286 CONFIG_XPS=y
287 CONFIG_ZONE_DMA32=y
288+
289+# CONFIG_GPIOLIB is not set
290+# CONFIG_GPIO_AMDPT is not set
291+# CONFIG_GPIO_DWAPB is not set
292+# CONFIG_GPIO_GENERIC_PLATFORM is not set
293+# CONFIG_GPIO_ICH is not set
294+# CONFIG_GPIO_LYNXPOINT is not set
295+# CONFIG_GPIO_VX855 is not set
296+# CONFIG_GPIO_ZX is not set
297+# CONFIG_GPIO_104_IDIO_16 is not set
298+# CONFIG_GPIO_F7188X is not set
299+# CONFIG_GPIO_IT87 is not set
300+# CONFIG_GPIO_SCH is not set
301+# CONFIG_GPIO_SCH311X is not set
302+# CONFIG_GPIO_AMD8111 is not set
303+# CONFIG_GPIO_BT8XX is not set
304+# CONFIG_GPIO_INTEL_MID is not set
305+# CONFIG_GPIO_ML_IOH is not set
306+# CONFIG_GPIO_RDC321X is not set
307+
308diff -urN target.old/linux/generic/files/drivers/leds/leds-apu2.c target/linux/generic/files/drivers/leds/leds-apu2.c
309--- target.old/linux/generic/files/drivers/leds/leds-apu2.c 1969-12-31 19:00:00.000000000 -0500
310+++ target/linux/generic/files/drivers/leds/leds-apu2.c 2016-08-23 09:39:21.944178300 -0400
311@@ -0,0 +1,202 @@
312+/*
313+ * LEDs driver for PCEngines apu2
314+ *
315+ * Copyright (C) 2016 Christian Herzog <daduke@daduke.org>, based on
316+ * Petr Leibman's leds-alix
317+ * Based on leds-wrap.c
318+ *
319+ *
320+ * This program is free software; you can redistribute it and/or modify
321+ * it under the terms of the GNU General Public License version 2 as
322+ * published by the Free Software Foundation.
323+ */
324+
325+#include <linux/kernel.h>
326+#include <linux/module.h>
327+#include <linux/init.h>
328+#include <linux/platform_device.h>
329+#include <linux/leds.h>
330+#include <linux/err.h>
331+#include <asm/io.h>
332+#include <linux/io.h>
333+
334+#define DRVNAME "apu2-led"
335+
336+#define FCH_ACPI_MMIO_BASE 0xFED80000
337+#define FCH_GPIO_BASE (FCH_ACPI_MMIO_BASE + 0x1500)
338+#define FCH_GPIO_SIZE 0x300
339+#define GPIO_BIT_WRITE 22
340+static DEFINE_SPINLOCK ( gpio_lock);
341+
342+#define APU2_NUM_GPIO 4
343+static u8 gpio_offset[APU2_NUM_GPIO] = {89, 68, 69, 70};
344+
345+static void __iomem *gpio_addr[APU2_NUM_GPIO] = {NULL, NULL, NULL, NULL};
346+
347+static struct platform_device *pdev;
348+
349+static void apu2_led_set_1(struct led_classdev *led_cdev, enum led_brightness value) {
350+ u32 val;
351+
352+ spin_lock_bh (&gpio_lock);
353+
354+ val = ioread32 (gpio_addr[1]);
355+
356+ if (value)
357+ val &= ~BIT(GPIO_BIT_WRITE);
358+ else
359+ val |= BIT(GPIO_BIT_WRITE);
360+
361+ iowrite32 (val, gpio_addr[1]);
362+
363+ spin_unlock_bh (&gpio_lock);
364+}
365+
366+static void apu2_led_set_2(struct led_classdev *led_cdev, enum led_brightness value) {
367+ u32 val;
368+
369+ spin_lock_bh (&gpio_lock);
370+
371+ val = ioread32 (gpio_addr[2]);
372+
373+ if (value)
374+ val &= ~BIT(GPIO_BIT_WRITE);
375+ else
376+ val |= BIT(GPIO_BIT_WRITE);
377+
378+ iowrite32 (val, gpio_addr[2]);
379+
380+ spin_unlock_bh (&gpio_lock);
381+}
382+
383+static void apu2_led_set_3(struct led_classdev *led_cdev, enum led_brightness value) {
384+ u32 val;
385+
386+ spin_lock_bh (&gpio_lock);
387+
388+ val = ioread32 (gpio_addr[3]);
389+
390+ if (value)
391+ val &= ~BIT(GPIO_BIT_WRITE);
392+ else
393+ val |= BIT(GPIO_BIT_WRITE);
394+
395+ iowrite32 (val, gpio_addr[3]);
396+
397+ spin_unlock_bh (&gpio_lock);
398+}
399+
400+static struct led_classdev apu2_led_1 = {
401+ .name = "apu2:1",
402+ .brightness_set = apu2_led_set_1,
403+};
404+
405+static struct led_classdev apu2_led_2 = {
406+ .name = "apu2:2",
407+ .brightness_set = apu2_led_set_2,
408+};
409+
410+static struct led_classdev apu2_led_3 = {
411+ .name = "apu2:3",
412+ .brightness_set = apu2_led_set_3,
413+};
414+
415+#ifdef CONFIG_PM
416+static int apu2_led_suspend(struct platform_device *dev,
417+ pm_message_t state)
418+{
419+ led_classdev_suspend(&apu2_led_1);
420+ led_classdev_suspend(&apu2_led_2);
421+ led_classdev_suspend(&apu2_led_3);
422+ return 0;
423+}
424+
425+static int apu2_led_resume(struct platform_device *dev)
426+{
427+ led_classdev_resume(&apu2_led_1);
428+ led_classdev_resume(&apu2_led_2);
429+ led_classdev_resume(&apu2_led_3);
430+ return 0;
431+}
432+#else
433+#define apu2_led_suspend NULL
434+#define apu2_led_resume NULL
435+#endif
436+
437+static int apu2_led_probe(struct platform_device *pdev)
438+{
439+ int ret;
440+
441+ ret = led_classdev_register(&pdev->dev, &apu2_led_1);
442+ if (ret == 0)
443+ {
444+ ret = led_classdev_register(&pdev->dev, &apu2_led_2);
445+ if (ret >= 0)
446+ {
447+ ret = led_classdev_register(&pdev->dev, &apu2_led_3);
448+ if (ret < 0)
449+ led_classdev_unregister(&apu2_led_2);
450+ }
451+ if (ret < 0)
452+ led_classdev_unregister(&apu2_led_1);
453+ }
454+ return ret;
455+}
456+
457+static int apu2_led_remove(struct platform_device *pdev)
458+{
459+ led_classdev_unregister(&apu2_led_1);
460+ led_classdev_unregister(&apu2_led_2);
461+ led_classdev_unregister(&apu2_led_3);
462+
463+ return 0;
464+}
465+
466+static struct platform_driver apu2_led_driver = {
467+ .probe = apu2_led_probe,
468+ .remove = apu2_led_remove,
469+ .suspend = apu2_led_suspend,
470+ .resume = apu2_led_resume,
471+ .driver = {
472+ .name = DRVNAME,
473+ .owner = THIS_MODULE,
474+ },
475+};
476+
477+static int __init apu2_led_init(void)
478+{
479+ int ret;
480+ int i;
481+
482+ ret = platform_driver_register(&apu2_led_driver);
483+ if (ret < 0)
484+ goto out;
485+
486+ pdev = platform_device_register_simple(DRVNAME, -1, NULL, 0);
487+ if (IS_ERR(pdev)) {
488+ ret = PTR_ERR(pdev);
489+ platform_driver_unregister(&apu2_led_driver);
490+ goto out;
491+ }
492+
493+ for (i = 0; i < APU2_NUM_GPIO; i++) {
494+ gpio_addr[i] = ioremap ( FCH_GPIO_BASE + (gpio_offset[i] * sizeof (u32)), sizeof (u32));
495+ }
496+
497+out:
498+ return ret;
499+}
500+
501+static void __exit apu2_led_exit(void)
502+{
503+ platform_device_unregister(pdev);
504+ platform_driver_unregister(&apu2_led_driver);
505+}
506+
507+module_init(apu2_led_init);
508+module_exit(apu2_led_exit);
509+
510+MODULE_AUTHOR("Christian Herzog");
511+MODULE_DESCRIPTION("PCEngines apu2 LED driver");
512+MODULE_LICENSE("GPL");
513+
514diff -urN target.old/linux/x86/modules.mk target/linux/x86/modules.mk
515--- target.old/linux/x86/modules.mk 2017-01-14 00:16:47.236215400 -0500
516+++ target/linux/x86/modules.mk 2017-01-14 00:17:28.844215400 -0500
517@@ -19,3 +19,18 @@
518 endef
519
520 $(eval $(call KernelPackage,sound-cs5535audio))
521+
522+define KernelPackage/sp5100_tco
523+ SUBMENU:=$(OTHER_MENU)
524+ TITLE:=SP5100 Watchdog Support
525+ DEPENDS:=@TARGET_x86
526+ KCONFIG:=CONFIG_SP5100_TCO
527+ FILES:=$(LINUX_DIR)/drivers/watchdog/sp5100_tco.ko
528+ AUTOLOAD:=$(call AutoLoad,50,sp5100_tco,1)
529+endef
530+
531+define KernelPackage/sp5100_tco/description
532+ Kernel module for the SP5100_TCO hardware watchdog.
533+endef
534+
535+$(eval $(call KernelPackage,sp5100_tco))