diff --git a/arch/arm/configs/htcleo_defconfig b/arch/arm/configs/htcleo_defconfig index ac80c8c0..b97d0302 100644 --- a/arch/arm/configs/htcleo_defconfig +++ b/arch/arm/configs/htcleo_defconfig @@ -1118,7 +1118,9 @@ CONFIG_SENSORS_AKM8973=y # CONFIG_I2C_DEBUG_ALGO is not set # CONFIG_I2C_DEBUG_BUS is not set # CONFIG_I2C_DEBUG_CHIP is not set -# CONFIG_SPI is not set +CONFIG_SPI=y +CONFIG_SPI_MASTER=y +CONFIG_SPI_QSD=y # # PPS support diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile index 093106e0..847d9811 100644 --- a/arch/arm/mach-msm/Makefile +++ b/arch/arm/mach-msm/Makefile @@ -114,7 +114,7 @@ obj-$(CONFIG_MACH_BRAVOC) += board-bravoc-rfkill.o board-bravoc-audio.o obj-$(CONFIG_MACH_BRAVOC) += board-bravoc-wifi.o htc_awb_cal.o obj-$(CONFIG_MACH_BRAVOC) += board-bravoc-microp.o clock.o -obj-$(CONFIG_MACH_HTCLEO) += board-htcleo.o board-htcleo-spi.o board-htcleo-panel.o board-htcleo-keypad.o +obj-$(CONFIG_MACH_HTCLEO) += board-htcleo.o board-htcleo-panel.o board-htcleo-keypad.o obj-$(CONFIG_MACH_HTCLEO) += board-htcleo-ts.o board-htcleo-mmc.o ieee754-df.o board-htcleo-power.o obj-$(CONFIG_MACH_HTCLEO) += board-htcleo-battery.o board-htcleo-log.o board-htcleo-audio.o board-htcleo-acoustic.o diff --git a/arch/arm/mach-msm/board-htcleo-panel.c b/arch/arm/mach-msm/board-htcleo-panel.c index 730aaa56..1f5bcff1 100644 --- a/arch/arm/mach-msm/board-htcleo-panel.c +++ b/arch/arm/mach-msm/board-htcleo-panel.c @@ -56,9 +56,6 @@ static struct vreg *vreg_lcd; #define LCM_DELAY(a) msleep(a) -// from board-htcleo-spi.c -extern void qspi_enable(); -extern void qspi_disable(); extern int qspi_send_9bit(unsigned char id, unsigned data); extern int qspi_send_16bit(unsigned char id, unsigned data); extern int qspi_send(unsigned char id, unsigned data); @@ -642,7 +639,6 @@ static void auo_panel_cfg_setup(int on) spisize = ARRAY_SIZE(AUO_DEINIT) / 6; } - qspi_enable(); for (i = 0; i < spisize; i++) { ret = qspi_send_16bit(spiseq[i].reg, spiseq[i].val); @@ -655,7 +651,6 @@ static void auo_panel_cfg_setup(int on) LCM_DELAY(spiseq[i].delay); } } - qspi_disable(); } static int auo_panel_init(struct msm_lcdc_panel_ops *ops) @@ -740,7 +735,6 @@ static void sharp_panel_cfg_setup(int on) spisize = ARRAY_SIZE(SHARP_DEINIT) / 6; } - qspi_enable(); for (i = 0; i < spisize; i++) { ret = qspi_send_9bit(spiseq[i].reg, spiseq[i].val); @@ -753,7 +747,6 @@ static void sharp_panel_cfg_setup(int on) LCM_DELAY(spiseq[i].delay); } } - qspi_disable(); } static int sharp_panel_init(struct msm_lcdc_panel_ops *ops) diff --git a/arch/arm/mach-msm/board-htcleo-spi.c b/arch/arm/mach-msm/board-htcleo-spi.c deleted file mode 100644 index 48eb0959..00000000 --- a/arch/arm/mach-msm/board-htcleo-spi.c +++ /dev/null @@ -1,201 +0,0 @@ -/* linux/driver/spi/spi_qsd.c -* -* Copyright (C) 2009 Solomon Chiu -* -* This is a temporary solution to substitute Qualcomm's SPI. -* Should be replaced by formal SPI driver in the future. -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define SPI_CONFIG (0x00000000) -#define SPI_IO_CONTROL (0x00000004) -#define SPI_OPERATIONAL (0x00000030) -#define SPI_ERROR_FLAGS_EN (0x00000038) -#define SPI_ERROR_FLAGS (0x00000038) -#define SPI_OUTPUT_FIFO (0x00000100) - -static void __iomem *spi_base; -static struct clk *spi_clk ; -static int clock_state; - -void qspi_enable() -{ - clk_enable(spi_clk); - clock_state = 1; -} - -void qspi_disable() -{ - clock_state = 0; - clk_disable(spi_clk); -} - -int qspi_send_16bit(unsigned char id, unsigned data) -{ - unsigned err ; - - if (!clock_state) - return -1; - - /* bit-5: OUTPUT_FIFO_NOT_EMPTY */ - while( readl(spi_base+SPI_OPERATIONAL) & (1<<5) ) - { - if( (err=readl(spi_base+SPI_ERROR_FLAGS)) ) - { - printk("\rERROR: SPI_ERROR_FLAGS=%d\r", err); - return -1; - } - } - - writel( (id<<13 | data)<<16, spi_base+SPI_OUTPUT_FIFO );/*AUO*/ - udelay(1000); - - return 0; -} - -int qspi_send_9bit(unsigned char id, unsigned data) -{ - unsigned err ; - - if (!clock_state) - return -1; - - /* bit-5: OUTPUT_FIFO_NOT_EMPTY */ - - while( readl(spi_base+SPI_OPERATIONAL) & (1<<5) ) - { - if( (err=readl(spi_base+SPI_ERROR_FLAGS)) ) - { - printk("\rERROR: SPI_ERROR_FLAGS=%d\r", err); - return -1; - } - } - - writel( ((id<<8) | data)<<23, spi_base+SPI_OUTPUT_FIFO);/*sharp*/ - - udelay(1000); - - return 0; -} - - -int qspi_send(unsigned char id, unsigned data) -{ - unsigned err ; - - if (!clock_state) - return -1; - - /* bit-5: OUTPUT_FIFO_NOT_EMPTY */ - - while( readl(spi_base+SPI_OPERATIONAL) & (1<<5) ) - { - if( (err=readl(spi_base+SPI_ERROR_FLAGS)) ) - { - printk("\rERROR: SPI_ERROR_FLAGS=%d\r", err); - return -1; - } - } - - writel( (0x7000 | id<<9 | data)<<16, spi_base+SPI_OUTPUT_FIFO ); - udelay(100); - - return 0; -} - -static int __init msm_spi_probe(struct platform_device *pdev) -{ - int rc ; - - spi_base=ioremap(0xA1200000, 4096); - if(!spi_base) - return -1; - - spi_clk = clk_get(&pdev->dev, "spi_clk"); - if (IS_ERR(spi_clk)) { - dev_err(&pdev->dev, "%s: unable to get spi_clk\n", __func__); - rc = PTR_ERR(spi_clk); - goto err_probe_clk_get; - } - rc = clk_enable(spi_clk); - if (rc) { - dev_err(&pdev->dev, "%s: unable to enable spi_clk\n", - __func__); - goto err_probe_clk_enable; - } - -// CotullaTODO: set same speed as in CE - // if(pdata == NULL) - clk_set_rate(spi_clk, 4800000); - // else - // clk_set_rate(spi_clk, pdata->clk_rate); - - printk(KERN_DEBUG "spi clk = 0x%ld\n", clk_get_rate(spi_clk)); - printk("spi: SPI_CONFIG=%x\n", readl(spi_base+SPI_CONFIG)); - printk("spi: SPI_IO_CONTROL=%x\n", readl(spi_base+SPI_IO_CONTROL)); - printk("spi: SPI_OPERATIONAL=%x\n", readl(spi_base+SPI_OPERATIONAL)); - printk("spi: SPI_ERROR_FLAGS_EN=%x\n", readl(spi_base+SPI_ERROR_FLAGS_EN)); - printk("spi: SPI_ERROR_FLAGS=%x\n", readl(spi_base+SPI_ERROR_FLAGS)); - printk("-%s()\n", __FUNCTION__); - clk_disable(spi_clk); - - return 0 ; - -err_probe_clk_get: -err_probe_clk_enable: - return -1 ; -} - -static int __devexit msm_spi_remove(struct platform_device *pdev) -{ - return 0; -} - -static int msm_spi_suspend(struct platform_device *pdev, pm_message_t state) -{ - printk("+%s()\n", __FUNCTION__); - clk_disable(spi_clk); - return 0 ; -} - -static int msm_spi_resume(struct platform_device *pdev) -{ - printk("+%s()\n", __FUNCTION__); - clk_enable(spi_clk); - return 0 ; -} - -static struct platform_driver msm_spi_driver = { - .probe = msm_spi_probe, - .driver = { - .name = "spi_qsd", - .owner = THIS_MODULE, - }, -#if 0 - .suspend = msm_spi_suspend, - .resume = msm_spi_resume, -#endif - .remove = __exit_p(msm_spi_remove), -}; - -static int __init msm_spi_init(void) -{ - return platform_driver_register(&msm_spi_driver); -} - -fs_initcall(msm_spi_init); diff --git a/arch/arm/mach-msm/board-htcleo.c b/arch/arm/mach-msm/board-htcleo.c index a66d6d88..32355939 100644 --- a/arch/arm/mach-msm/board-htcleo.c +++ b/arch/arm/mach-msm/board-htcleo.c @@ -28,6 +28,7 @@ #include #include #include +#include #ifdef CONFIG_SENSORS_BMA150_SPI #include #endif @@ -90,15 +91,6 @@ static int __init parse_tag_nand_boot(const struct tag *tag) __tagtable(ATAG_MAGLDR_BOOT, parse_tag_nand_boot); -/////////////////////////////////////////////////////////////////////// -// SPI -/////////////////////////////////////////////////////////////////////// - -static struct platform_device qsd_device_spi = -{ - .name = "spi_qsd", - .id = 0, -}; /////////////////////////////////////////////////////////////////////// // Regulator @@ -523,6 +515,87 @@ static struct platform_device htcleo_rfkill = .id = -1, }; +/////////////////////////////////////////////////////////////////////// +// SPI +/////////////////////////////////////////////////////////////////////// + +static struct resource qsd_spi_resources[] = { + { + .name = "spi_irq_in", + .start = INT_SPI_INPUT, + .end = INT_SPI_INPUT, + .flags = IORESOURCE_IRQ, + }, + { + .name = "spi_irq_out", + .start = INT_SPI_OUTPUT, + .end = INT_SPI_OUTPUT, + .flags = IORESOURCE_IRQ, + }, + { + .name = "spi_irq_err", + .start = INT_SPI_ERROR, + .end = INT_SPI_ERROR, + .flags = IORESOURCE_IRQ, + }, + { + .name = "spi_base", + .start = 0xA1200000, + .end = 0xA1200000 + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + { + .name = "spi_clk", + .start = 17, + .end = 1, + .flags = IORESOURCE_IRQ, + }, + { + .name = "spi_mosi", + .start = 18, + .end = 1, + .flags = IORESOURCE_IRQ, + }, + { + .name = "spi_miso", + .start = 19, + .end = 1, + .flags = IORESOURCE_IRQ, + }, + { + .name = "spi_cs0", + .start = 20, + .end = 1, + .flags = IORESOURCE_IRQ, + }, + { + .name = "spi_pwr", + .start = 21, + .end = 0, + .flags = IORESOURCE_IRQ, + }, + { + .name = "spi_irq_cs0", + .start = 22, + .end = 0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct spi_platform_data htcleo_spi_pdata = { + .clk_rate = 4800000, +}; + +static struct platform_device qsd_device_spi = { + .name = "spi_qsd", + .id = 0, + .num_resources = ARRAY_SIZE(qsd_spi_resources), + .resource = qsd_spi_resources, + .dev = { + .platform_data = &htcleo_spi_pdata + }, +}; + /////////////////////////////////////////////////////////////////////// // KGSL (HW3D support)#include ///////////////////////////////////////////////////////////////////////