Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3) // Copyright (C) 2010 Maurus Cuelenaere
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) #include <linux/fb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) #include <linux/gpio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include <linux/gpio/machine.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/pwm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/pwm_backlight.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/serial_core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/serial_s3c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/spi/spi_gpio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/platform_data/s3c-hsotg.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <asm/mach-types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <asm/mach/map.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include "map.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #include "regs-gpio.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #include "gpio-samsung.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #include "cpu.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #include "devs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #include <linux/platform_data/i2c-s3c2410.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #include "gpio-cfg.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) #include <linux/platform_data/hwmon-s3c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) #include <linux/platform_data/usb-ohci-s3c2410.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) #include "sdhci.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) #include <linux/platform_data/touchscreen-s3c2410.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) #include <video/platform_lcd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) #include "s3c64xx.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) #include "mach-smartq.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) #include "regs-modem-s3c64xx.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) #define UCON S3C2410_UCON_DEFAULT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) #define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) #define UFCON (S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) static struct s3c2410_uartcfg smartq_uartcfgs[] __initdata = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	[0] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 		.hwport	     = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 		.flags	     = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 		.ucon	     = UCON,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 		.ulcon	     = ULCON,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 		.ufcon	     = UFCON,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	[1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 		.hwport	     = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 		.flags	     = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 		.ucon	     = UCON,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 		.ulcon	     = ULCON,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 		.ufcon	     = UFCON,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	[2] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 		.hwport	     = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 		.flags	     = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 		.ucon	     = UCON,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 		.ulcon	     = ULCON,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 		.ufcon	     = UFCON,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) static void smartq_usb_host_powercontrol(int port, int to)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	pr_debug("%s(%d, %d)\n", __func__, port, to);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	if (port == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 		gpio_set_value(S3C64XX_GPL(0), to);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 		gpio_set_value(S3C64XX_GPL(1), to);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) static irqreturn_t smartq_usb_host_ocirq(int irq, void *pw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	struct s3c2410_hcd_info *info = pw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	if (gpio_get_value(S3C64XX_GPL(10)) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 		pr_debug("%s: over-current irq (oc detected)\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 		s3c2410_usb_report_oc(info, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 		pr_debug("%s: over-current irq (oc cleared)\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 		s3c2410_usb_report_oc(info, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) static void smartq_usb_host_enableoc(struct s3c2410_hcd_info *info, int on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	/* This isn't present on a SmartQ 5 board */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	if (machine_is_smartq5())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	if (on) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 		ret = request_irq(gpio_to_irq(S3C64XX_GPL(10)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 				  smartq_usb_host_ocirq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 				  IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 				  "USB host overcurrent", info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 		if (ret != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 			pr_err("failed to request usb oc irq: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 		free_irq(gpio_to_irq(S3C64XX_GPL(10)), info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) static struct s3c2410_hcd_info smartq_usb_host_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	.port[0]	= {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 		.flags	= S3C_HCDFLG_USED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	.port[1]	= {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 		.flags	= 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	.power_control	= smartq_usb_host_powercontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	.enable_oc	= smartq_usb_host_enableoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) static struct gpiod_lookup_table smartq_usb_otg_vbus_gpiod_table = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	.dev_id = "gpio-vbus",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	.table = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 		GPIO_LOOKUP("GPL", 9, "vbus", GPIO_ACTIVE_LOW),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 		{ },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) static struct platform_device smartq_usb_otg_vbus_dev = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	.name			= "gpio-vbus",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) static struct pwm_lookup smartq_pwm_lookup[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	PWM_LOOKUP("samsung-pwm", 1, "pwm-backlight.0", NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 		   1000000000 / (1000 * 20), PWM_POLARITY_NORMAL),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) static int smartq_bl_init(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)     s3c_gpio_cfgpin(S3C64XX_GPF(15), S3C_GPIO_SFN(2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)     return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) static struct platform_pwm_backlight_data smartq_backlight_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	.max_brightness	= 1000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	.dft_brightness	= 600,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	.init		= smartq_bl_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) static struct platform_device smartq_backlight_device = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	.name		= "pwm-backlight",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	.dev		= {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 		.parent	= &samsung_device_pwm.dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 		.platform_data = &smartq_backlight_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) static struct s3c2410_ts_mach_info smartq_touchscreen_pdata __initdata = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	.delay			= 65535,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	.presc			= 99,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	.oversampling_shift	= 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) static struct s3c_sdhci_platdata smartq_internal_hsmmc_pdata = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	.max_width		= 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	.cd_type		= S3C_SDHCI_CD_PERMANENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) static struct s3c_hwmon_pdata smartq_hwmon_pdata __initdata = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	/* Battery voltage (?-4.2V) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	.in[0] = &(struct s3c_hwmon_chcfg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 		.name		= "smartq:battery-voltage",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 		.mult		= 3300,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 		.div		= 2048,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	/* Reference voltage (1.2V) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	.in[1] = &(struct s3c_hwmon_chcfg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 		.name		= "smartq:reference-voltage",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 		.mult		= 3300,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 		.div		= 4096,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) static struct dwc2_hsotg_plat smartq_hsotg_pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) static int __init smartq_lcd_setup_gpio(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	ret = gpio_request(S3C64XX_GPM(3), "LCD power");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 	/* turn power off */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 	gpio_direction_output(S3C64XX_GPM(3), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) /* GPM0 -> CS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) static struct spi_gpio_platform_data smartq_lcd_control = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 	.num_chipselect	= 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) static struct platform_device smartq_lcd_control_device = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 	.name			= "spi_gpio",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 	.id			= 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 	.dev.platform_data	= &smartq_lcd_control,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) static struct gpiod_lookup_table smartq_lcd_control_gpiod_table = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 	.dev_id         = "spi_gpio",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 	.table          = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 		GPIO_LOOKUP("GPIOM", 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 			    "sck", GPIO_ACTIVE_HIGH),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 		GPIO_LOOKUP("GPIOM", 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 			    "mosi", GPIO_ACTIVE_HIGH),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 		GPIO_LOOKUP("GPIOM", 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 			    "miso", GPIO_ACTIVE_HIGH),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 		GPIO_LOOKUP("GPIOM", 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 			    "cs", GPIO_ACTIVE_HIGH),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 		{ },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) static void smartq_lcd_power_set(struct plat_lcd_data *pd, unsigned int power)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 	gpio_direction_output(S3C64XX_GPM(3), power);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) static struct plat_lcd_data smartq_lcd_power_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 	.set_power	= smartq_lcd_power_set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) static struct platform_device smartq_lcd_power_device = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 	.name			= "platform-lcd",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 	.dev.parent		= &s3c_device_fb.dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 	.dev.platform_data	= &smartq_lcd_power_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) static struct i2c_board_info smartq_i2c_devs[] __initdata = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 	{ I2C_BOARD_INFO("wm8987", 0x1a), },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) static struct platform_device *smartq_devices[] __initdata = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	&s3c_device_hsmmc1,	/* Init iNAND first, ... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	&s3c_device_hsmmc0,	/* ... then the external SD card */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 	&s3c_device_hsmmc2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 	&s3c_device_adc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	&s3c_device_fb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 	&s3c_device_hwmon,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 	&s3c_device_i2c0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 	&s3c_device_ohci,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 	&s3c_device_rtc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	&samsung_device_pwm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 	&s3c_device_usb_hsotg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 	&s3c64xx_device_iis0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 	&smartq_backlight_device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 	&smartq_lcd_control_device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 	&smartq_lcd_power_device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 	&smartq_usb_otg_vbus_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) static void __init smartq_lcd_mode_set(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 	u32 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 	/* set the LCD type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 	tmp = __raw_readl(S3C64XX_SPCON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 	tmp &= ~S3C64XX_SPCON_LCD_SEL_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 	tmp |= S3C64XX_SPCON_LCD_SEL_RGB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 	__raw_writel(tmp, S3C64XX_SPCON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 	/* remove the LCD bypass */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 	tmp = __raw_readl(S3C64XX_MODEM_MIFPCON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 	tmp &= ~MIFPCON_LCD_BYPASS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 	__raw_writel(tmp, S3C64XX_MODEM_MIFPCON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) static void smartq_power_off(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 	gpio_direction_output(S3C64XX_GPK(15), 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) static int __init smartq_power_off_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 	ret = gpio_request(S3C64XX_GPK(15), "Power control");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 		pr_err("%s: failed to get GPK15\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 	/* leave power on */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 	gpio_direction_output(S3C64XX_GPK(15), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 	pm_power_off = smartq_power_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) static int __init smartq_usb_host_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 	ret = gpio_request(S3C64XX_GPL(0), "USB power control");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 		pr_err("%s: failed to get GPL0\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 	ret = gpio_request(S3C64XX_GPL(1), "USB host power control");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 		pr_err("%s: failed to get GPL1\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 		goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 	if (!machine_is_smartq5()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 		/* This isn't present on a SmartQ 5 board */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 		ret = gpio_request(S3C64XX_GPL(10), "USB host overcurrent");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 		if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 			pr_err("%s: failed to get GPL10\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 			goto err2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 	/* turn power off */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 	gpio_direction_output(S3C64XX_GPL(0), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 	gpio_direction_output(S3C64XX_GPL(1), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 	if (!machine_is_smartq5())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 		gpio_direction_input(S3C64XX_GPL(10));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 	s3c_device_ohci.dev.platform_data = &smartq_usb_host_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) err2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 	gpio_free(S3C64XX_GPL(1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 	gpio_free(S3C64XX_GPL(0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) static int __init smartq_wifi_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 	ret = gpio_request(S3C64XX_GPK(1), "wifi control");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 		pr_err("%s: failed to get GPK1\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 	ret = gpio_request(S3C64XX_GPK(2), "wifi reset");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 		pr_err("%s: failed to get GPK2\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 		gpio_free(S3C64XX_GPK(1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 	/* turn power on */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 	gpio_direction_output(S3C64XX_GPK(1), 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 	/* reset device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 	gpio_direction_output(S3C64XX_GPK(2), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 	mdelay(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 	gpio_set_value(S3C64XX_GPK(2), 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 	gpio_direction_input(S3C64XX_GPK(2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) static struct map_desc smartq_iodesc[] __initdata = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) void __init smartq_map_io(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 	s3c64xx_init_io(smartq_iodesc, ARRAY_SIZE(smartq_iodesc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 	s3c64xx_set_xtal_freq(12000000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 	s3c64xx_set_xusbxti_freq(12000000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 	s3c24xx_init_uarts(smartq_uartcfgs, ARRAY_SIZE(smartq_uartcfgs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 	s3c64xx_set_timer_source(S3C64XX_PWM3, S3C64XX_PWM4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 	smartq_lcd_mode_set();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) static struct gpiod_lookup_table smartq_audio_gpios = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 	.dev_id = "smartq-audio",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 	.table = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 		GPIO_LOOKUP("GPL", 12, "headphone detect", 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 		GPIO_LOOKUP("GPK", 12, "amplifiers shutdown", 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 		{ },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) void __init smartq_machine_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 	s3c_i2c0_set_platdata(NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 	dwc2_hsotg_set_platdata(&smartq_hsotg_pdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 	s3c_hwmon_set_platdata(&smartq_hwmon_pdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 	s3c_sdhci1_set_platdata(&smartq_internal_hsmmc_pdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 	s3c_sdhci2_set_platdata(&smartq_internal_hsmmc_pdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 	s3c64xx_ts_set_platdata(&smartq_touchscreen_pdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 	i2c_register_board_info(0, smartq_i2c_devs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 				ARRAY_SIZE(smartq_i2c_devs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 	WARN_ON(smartq_lcd_setup_gpio());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 	WARN_ON(smartq_power_off_init());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 	WARN_ON(smartq_usb_host_init());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 	WARN_ON(smartq_wifi_init());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 	pwm_add_table(smartq_pwm_lookup, ARRAY_SIZE(smartq_pwm_lookup));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 	gpiod_add_lookup_table(&smartq_lcd_control_gpiod_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 	gpiod_add_lookup_table(&smartq_usb_otg_vbus_gpiod_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 	platform_add_devices(smartq_devices, ARRAY_SIZE(smartq_devices));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 	gpiod_add_lookup_table(&smartq_audio_gpios);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 	platform_device_register_simple("smartq-audio", -1, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) }