Advertisement
Guest User

ADC/TS driver for i.MX25 (3.3 and 2.6.x kernel series)

a guest
Apr 30th, 2012
319
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Diff 67.79 KB | None | 0 0
  1. From 9e2c0e5d074347b86d6cfdc7888d145c0c9c00ea Mon Sep 17 00:00:00 2001
  2. From: Roberto Nibali <rnibali@gmail.com>
  3. Date: Tue, 13 Mar 2012 16:14:39 +0100
  4. Subject: [PATCH 14/24] This mainly adds the ADC/TS driver developed by Juergen Beisert
  5.  from Pengutronix.
  6.  
  7. ---
  8. arch/arm/mach-imx/Kconfig                       |    4 +
  9.  arch/arm/mach-imx/clock-imx25.c                 |   39 ++-
  10.  arch/arm/mach-imx/devices-imx25.h               |    4 +
  11.  arch/arm/plat-mxc/Makefile                      |    1 +
  12.  arch/arm/plat-mxc/adc-v1.c                      |  448 ++++++++++++++
  13.  arch/arm/plat-mxc/devices/Makefile              |    1 +
  14.  arch/arm/plat-mxc/devices/platform-imx-adc.c    |   61 ++
  15.  arch/arm/plat-mxc/imx-hwmon.c                   |  146 +++++
  16.  arch/arm/plat-mxc/imx-ts.c                      |  749 +++++++++++++++++++++++
  17.  arch/arm/plat-mxc/include/mach/adc.h            |   47 ++
  18.  arch/arm/plat-mxc/include/mach/devices-common.h |   14 +
  19.  arch/arm/plat-mxc/include/mach/imxfb.h          |    2 +
  20.  arch/arm/plat-mxc/include/mach/iomux-mx25.h     |    9 +-
  21.  arch/arm/plat-mxc/include/mach/mx25.h           |    2 +
  22.  drivers/video/backlight/pwm_bl.c                |   10 +-
  23.  drivers/video/imxfb.c                           |  265 +++++++--
  24.  include/linux/platform_data/imx-adc.h           |   54 ++
  25.  17 files changed, 1789 insertions(+), 67 deletions(-)
  26.  create mode 100644 arch/arm/plat-mxc/adc-v1.c
  27.  create mode 100644 arch/arm/plat-mxc/devices/platform-imx-adc.c
  28.  create mode 100644 arch/arm/plat-mxc/imx-hwmon.c
  29.  create mode 100644 arch/arm/plat-mxc/imx-ts.c
  30.  create mode 100644 arch/arm/plat-mxc/include/mach/adc.h
  31.  create mode 100644 include/linux/platform_data/imx-adc.h
  32.  
  33. diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
  34. index 4defb97..7c71286 100644
  35. --- a/arch/arm/mach-imx/Kconfig
  36. +++ b/arch/arm/mach-imx/Kconfig
  37. @@ -1,6 +1,9 @@
  38.  config IMX_HAVE_DMA_V1
  39.     bool
  40.  
  41. +config IMX_HAVE_ADC_V1
  42. +   bool
  43. +
  44.  config HAVE_IMX_GPC
  45.     bool
  46.  
  47. @@ -56,6 +59,7 @@ config SOC_IMX25
  48.     select ARCH_MX25
  49.     select CPU_ARM926T
  50.     select ARCH_MXC_AUDMUX_V2
  51. +   select IMX_HAVE_ADC_V1
  52.     select ARCH_MXC_IOMUX_V3
  53.     select MXC_AVIC
  54.  
  55. diff --git a/arch/arm/mach-imx/clock-imx25.c b/arch/arm/mach-imx/clock-imx25.c
  56. index b0fec74c..e42b0a5 100644
  57. --- a/arch/arm/mach-imx/clock-imx25.c
  58. +++ b/arch/arm/mach-imx/clock-imx25.c
  59. @@ -33,6 +33,9 @@
  60.  #define CCM_MPCTL  0x00
  61.  #define CCM_UPCTL  0x04
  62.  #define CCM_CCTL   0x08
  63. +# define CCM_CCTL_UPLL_RST (1 << 26)
  64. +# define CCM_CCTL_UPLL_DIS (1 << 23)
  65. +# define CCM_CCTL_MPLL_BYPASS (1 << 22)
  66.  #define CCM_CGCR0  0x0C
  67.  #define CCM_CGCR1  0x10
  68.  #define CCM_CGCR2  0x14
  69. @@ -54,15 +57,23 @@
  70.  static unsigned long get_rate_mpll(void)
  71.  {
  72.     ulong mpctl = __raw_readl(CRM_BASE + CCM_MPCTL);
  73. +   u32 ctrl = __raw_readl(CRM_BASE + CCM_CCTL);
  74. +
  75. +   if (ctrl & CCM_CCTL_MPLL_BYPASS)
  76. +       return 24000000;
  77.  
  78.     return mxc_decode_pll(mpctl, 24000000);
  79.  }
  80.  
  81.  static unsigned long get_rate_upll(void)
  82.  {
  83. -   ulong mpctl = __raw_readl(CRM_BASE + CCM_UPCTL);
  84. +   ulong upctl = __raw_readl(CRM_BASE + CCM_UPCTL);
  85. +   u32 ctrl = __raw_readl(CRM_BASE + CCM_CCTL);
  86.  
  87. -   return mxc_decode_pll(mpctl, 24000000);
  88. +   if (ctrl & CCM_CCTL_UPLL_DIS)
  89. +       return 0;
  90. +
  91. +   return mxc_decode_pll(upctl, 24000000);
  92.  }
  93.  
  94.  unsigned long get_rate_arm(struct clk *clk)
  95. @@ -293,7 +304,7 @@ static struct clk_lookup lookups[] = {
  96.     _REGISTER_CLOCK("mxc_pwm.2", NULL, pwm3_clk)
  97.     _REGISTER_CLOCK("mxc_pwm.3", NULL, pwm4_clk)
  98.     _REGISTER_CLOCK("imx-keypad", NULL, kpp_clk)
  99. -   _REGISTER_CLOCK("mx25-adc", NULL, tsc_clk)
  100. +   _REGISTER_CLOCK("mx25-adc.0", NULL, tsc_clk)
  101.     _REGISTER_CLOCK("imx-i2c.0", NULL, i2c_clk)
  102.     _REGISTER_CLOCK("imx-i2c.1", NULL, i2c_clk)
  103.     _REGISTER_CLOCK("imx-i2c.2", NULL, i2c_clk)
  104. @@ -314,6 +325,27 @@ static struct clk_lookup lookups[] = {
  105.     _REGISTER_CLOCK(NULL, "iim", iim_clk)
  106.  };
  107.  
  108. +/*
  109. + * check, if the UPLL is up and running. Some bootloaders forget to
  110. + * enable it, but some of our peripherals rely on it.
  111. + */
  112. +static void __init mx25_init_upll(void)
  113. +{
  114. +   u32 reg, ctrl = __raw_readl(CRM_BASE + CCM_CCTL);
  115. +
  116. +   if (!(ctrl & CCM_CCTL_UPLL_DIS)) /* already enabled? */
  117. +       return;
  118. +
  119. +   pr_warn("%s: UPLL disabled. Enabling it\n", __func__);
  120. +   /* re-set the default value of 240 MHz */
  121. +   __raw_writel(0x00001400, CRM_BASE + CCM_UPCTL);
  122. +
  123. +   reg = __raw_readl(CRM_BASE + CCM_CCTL);
  124. +   reg &= ~(CCM_CCTL_UPLL_DIS | (0x3f << 16)); /* enable the UPLL */
  125. +   reg |= CCM_CCTL_UPLL_RST | (0x03 << 16);
  126. +   __raw_writel(reg, CRM_BASE + CCM_CCTL);
  127. +}
  128. +
  129.  int __init mx25_clocks_init(void)
  130.  {
  131.     clkdev_add_table(lookups, ARRAY_SIZE(lookups));
  132. @@ -328,6 +360,7 @@ int __init mx25_clocks_init(void)
  133.  #if defined(CONFIG_DEBUG_LL) && !defined(CONFIG_DEBUG_ICEDCC)
  134.     clk_enable(&uart1_clk);
  135.  #endif
  136. +   mx25_init_upll();
  137.  
  138.     /* Clock source for lcdc and csi is upll */
  139.     __raw_writel(__raw_readl(CRM_BASE+0x64) | (1 << 7) | (1 << 0),
  140. diff --git a/arch/arm/mach-imx/devices-imx25.h b/arch/arm/mach-imx/devices-imx25.h
  141. index efa0761..70d047c 100644
  142. --- a/arch/arm/mach-imx/devices-imx25.h
  143. +++ b/arch/arm/mach-imx/devices-imx25.h
  144. @@ -35,6 +35,10 @@ extern const struct imx_imx_fb_data imx25_imx_fb_data;
  145.  #define imx25_add_imx_fb(pdata)    \
  146.     imx_add_imx_fb(&imx25_imx_fb_data, pdata)
  147.  
  148. +extern const struct imx_imx_adc_data imx25_imx_adc_data;
  149. +#define imx25_add_imx_adc(pdata1, pdata2, pdata3)  \
  150. +   imx_add_imx_adc(&imx25_imx_adc_data, pdata1, pdata2, pdata3)
  151. +
  152.  extern const struct imx_imx_i2c_data imx25_imx_i2c_data[];
  153.  #define imx25_add_imx_i2c(id, pdata)   \
  154.     imx_add_imx_i2c(&imx25_imx_i2c_data[id], pdata)
  155. diff --git a/arch/arm/plat-mxc/Makefile b/arch/arm/plat-mxc/Makefile
  156. index 076db84f..a5c012b 100644
  157. --- a/arch/arm/plat-mxc/Makefile
  158. +++ b/arch/arm/plat-mxc/Makefile
  159. @@ -11,6 +11,7 @@ obj-$(CONFIG_MXC_AVIC) += avic.o
  160.  obj-$(CONFIG_IMX_HAVE_IOMUX_V1) += iomux-v1.o
  161.  obj-$(CONFIG_ARCH_MXC_IOMUX_V3) += iomux-v3.o
  162.  obj-$(CONFIG_IRAM_ALLOC) += iram_alloc.o
  163. +obj-$(CONFIG_IMX_HAVE_ADC_V1) += adc-v1.o imx-ts.o imx-hwmon.o
  164.  obj-$(CONFIG_MXC_PWM)  += pwm.o
  165.  obj-$(CONFIG_MXC_ULPI) += ulpi.o
  166.  obj-$(CONFIG_MXC_USE_EPIT) += epit.o
  167. diff --git a/arch/arm/plat-mxc/adc-v1.c b/arch/arm/plat-mxc/adc-v1.c
  168. new file mode 100644
  169. index 0000000..58917a0
  170. --- /dev/null
  171. +++ b/arch/arm/plat-mxc/adc-v1.c
  172. @@ -0,0 +1,448 @@
  173. +/*
  174. + * Copyright (C) 2011 Juergen Beisert, Pengutronix <kernel@pengutronix.de>
  175. + *
  176. + * This software is licensed under the terms of the GNU General Public
  177. + * License version 2, as published by the Free Software Foundation, and
  178. + * may be copied, distributed, and modified under those terms.
  179. + *
  180. + * This program is distributed in the hope that it will be useful,
  181. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  182. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  183. + * GNU General Public License for more details.
  184. + *
  185. + */
  186. +#undef DEBUG
  187. +
  188. +#include <linux/kernel.h>
  189. +#include <linux/module.h>
  190. +#include <linux/platform_device.h>
  191. +#include <linux/clk.h>
  192. +#include <linux/slab.h>
  193. +#include <linux/io.h>
  194. +#include <linux/err.h>
  195. +#include <linux/interrupt.h>
  196. +#include <linux/platform_data/imx-adc.h>
  197. +
  198. +#include <mach/adc.h>
  199. +
  200. +#define DRIVER_NAME "mx25-adc"
  201. +
  202. +#define TGCR 0
  203. +# define TGCR_SLPC (1 << 4)
  204. +# define TGCR_IPG_CLK_EN (1 << 0)
  205. +# define TGCR_TSC_RST (1 << 1)
  206. +# define TGCR_POWER_MASK (0x3 << 8)
  207. +# define TGCR_POWER_OFF (0 << 8)
  208. +# define TGCR_POWER_SAVE (1 << 8)
  209. +# define TGCR_POWER_ON (2 << 8)
  210. +# define TGCR_INTREFEN (1 << 10)
  211. +# define TGCR_CLKCFG_MASK (0x1f << 16)
  212. +# define TGCR_SET_CLKCFG(x) ((x) << 16)
  213. +
  214. +#define TGSR 4
  215. +
  216. +#define TICR 8
  217. +#define TCQCR
  218. +#define TCQCR
  219. +# define CQCR_PD_MSK
  220. +#define TCQMR
  221. +# define TCQMR_PD_IRQ_MSK
  222. +
  223. +struct imx_adc_device {
  224. +   struct platform_device *pdev;
  225. +   struct clk *clk;
  226. +   void __iomem *regs;
  227. +   void *ts;   /* only one instance allowed */
  228. +   irqreturn_t (*ts_irq)(void*);
  229. +   void *hwmon;    /* only one instance allowed */
  230. +   irqreturn_t (*hwmon_irq)(void*);
  231. +   int irq;
  232. +   unsigned adc_period; /* in [ns] */
  233. +   unsigned adc_freq; /* in [Hz] */
  234. +};
  235. +
  236. +/* there is only one instance per SoC */
  237. +static struct imx_adc_device *adc;
  238. +
  239. +/* --------- API to outer space ------------------ */
  240. +
  241. +void __iomem *imx_adc_get_iomem(void *imx_adc)
  242. +{
  243. +   struct imx_adc_device *adc = (struct imx_adc_device *)imx_adc;
  244. +   return adc->regs;
  245. +}
  246. +EXPORT_SYMBOL_GPL(imx_adc_get_iomem);
  247. +
  248. +void imx_adc_put_iomem(void __iomem *p, void *imx_adc)
  249. +{
  250. +//     struct imx_adc_device *adc = (struct imx_adc_device *)imx_adc;
  251. +}
  252. +EXPORT_SYMBOL_GPL(imx_adc_put_iomem);
  253. +
  254. +static void imx_wake_adc(struct imx_adc_device *adc)
  255. +{
  256. +   u32 reg;
  257. +
  258. +   reg = readl(adc->regs + TGCR) & ~TGCR_POWER_MASK;
  259. +   reg |= TGCR_POWER_SAVE | TGCR_INTREFEN;
  260. +   writel(reg, adc->regs + TGCR);
  261. +}
  262. +
  263. +static void imx_sleep_adc(struct imx_adc_device *adc)
  264. +{
  265. +   u32 reg;
  266. +
  267. +   reg = readl(adc->regs + TGCR) & ~(TGCR_POWER_MASK | TGCR_INTREFEN);
  268. +   reg |= TGCR_POWER_OFF;
  269. +   writel(reg, adc->regs + TGCR);
  270. +}
  271. +
  272. +void *imx_adc_register_ts(void *ts, irqreturn_t (*f)(void*))
  273. +{
  274. +   if (adc->ts != NULL)    /* FIXME locking */
  275. +       return ERR_PTR(-EBUSY);
  276. +   adc->ts = ts;
  277. +   adc->ts_irq = f;
  278. +
  279. +   /* now as a user is present, its time to wake the ADC */
  280. +   imx_wake_adc(adc);
  281. +   return (void *)adc;
  282. +}
  283. +EXPORT_SYMBOL_GPL(imx_adc_register_ts);
  284. +
  285. +int imx_adc_unregister_ts(void *imx_adc, void *ts)
  286. +{
  287. +   struct imx_adc_device *adc = (struct imx_adc_device *)imx_adc;
  288. +   if (adc->ts == NULL || adc->ts != ts)
  289. +       return -EINVAL;
  290. +   adc->ts = NULL;
  291. +   adc->ts_irq = NULL;
  292. +
  293. +   if (adc->hwmon == NULL) /* FIXME locking */
  294. +       imx_sleep_adc(adc);
  295. +
  296. +   return 0;
  297. +}
  298. +EXPORT_SYMBOL_GPL(imx_adc_unregister_ts);
  299. +
  300. +void *imx_adc_register_hwmon(void *hwmon, irqreturn_t (*f)(void*))
  301. +{
  302. +   if (adc->hwmon != NULL) /* FIXME locking */
  303. +       return ERR_PTR(-EBUSY);
  304. +   adc->hwmon = hwmon;
  305. +   adc->hwmon_irq = f;
  306. +
  307. +   /* now as a user is present, its time to wake the ADC */
  308. +   imx_wake_adc(adc);
  309. +   return (void *)adc;
  310. +}
  311. +EXPORT_SYMBOL_GPL(imx_adc_register_hwmon);
  312. +
  313. +int imx_adc_unregister_hwmon(void *imx_adc, void *hwmon)
  314. +{
  315. +   struct imx_adc_device *adc = (struct imx_adc_device *)imx_adc;
  316. +   if (adc->hwmon == NULL || adc->hwmon != hwmon)
  317. +       return -EINVAL;
  318. +   adc->hwmon = NULL;
  319. +   adc->hwmon_irq = NULL;
  320. +
  321. +   if (adc->ts == NULL)    /* FIXME locking */
  322. +       imx_sleep_adc(adc);
  323. +
  324. +   return 0;
  325. +}
  326. +EXPORT_SYMBOL_GPL(imx_adc_unregister_hwmon);
  327. +
  328. +unsigned imx_adc_get_period(void *imx_adc)
  329. +{
  330. +   struct imx_adc_device *adc = (struct imx_adc_device *)imx_adc;
  331. +   return adc->adc_period;
  332. +}
  333. +EXPORT_SYMBOL_GPL(imx_adc_get_period);
  334. +
  335. +void imx_adc_ts_set_tgcr(void *imx_adc, u32 val)
  336. +{
  337. +   struct imx_adc_device *adc = (struct imx_adc_device *)imx_adc;
  338. +   u32 reg;
  339. +
  340. +   /* restrict access to touchscreen relevant bits */
  341. +   val &= TGCR_PEN_DEBT_MASK | TGCR_PDBEN | TGCR_PDEN | TGCR_HSYNCEN | TGCR_HSYNCPOL;
  342. +   reg = readl(adc->regs + TGCR) &
  343. +               ~(TGCR_PEN_DEBT_MASK | TGCR_PDBEN | TGCR_PDEN | TGCR_HSYNCEN | TGCR_HSYNCPOL);
  344. +   writel(reg | val, adc->regs + TGCR);
  345. +   pr_info("Write TGCR with %08X\n", reg | val);
  346. +}
  347. +EXPORT_SYMBOL_GPL(imx_adc_ts_set_tgcr);
  348. +
  349. +/* --------- end of API to outer space ------------------ */
  350. +
  351. +static void mxc_adc_set_reg_bit(void __iomem *ofs, u32 bit)
  352. +{
  353. +   writel(readl(ofs) | bit, ofs);
  354. +}
  355. +
  356. +static void mxc_adc_clear_reg_bit(void __iomem *ofs, u32 bit)
  357. +{
  358. +   writel(readl(ofs) & ~bit, ofs);
  359. +}
  360. +
  361. +static void mxc_adc_enable_clk(struct imx_adc_device *adc)
  362. +{
  363. +   clk_enable(adc->clk);
  364. +   mxc_adc_set_reg_bit(adc->regs + TGCR, TGCR_IPG_CLK_EN);
  365. +}
  366. +
  367. +static void mxc_adc_disable_clk(struct imx_adc_device *adc)
  368. +{
  369. +   mxc_adc_clear_reg_bit(adc->regs + TGCR, TGCR_IPG_CLK_EN);
  370. +   clk_disable(adc->clk);
  371. +}
  372. +
  373. +static void mxc_adc_reset(struct imx_adc_device *adc)
  374. +{
  375. +   mxc_adc_set_reg_bit(adc->regs + TGCR, TGCR_TSC_RST);
  376. +
  377. +   /* TODO timeout */
  378. +   while (readl(adc->regs + TGCR) & TGCR_TSC_RST)
  379. +       ;
  380. +}
  381. +
  382. +static irqreturn_t mxc_adc_irq(int irq, void *pw)
  383. +{
  384. +   struct imx_adc_device *adc =(struct imx_adc_device *)pw;
  385. +   irqreturn_t ts_ret = IRQ_NONE, hwmon_ret = IRQ_NONE;
  386. +   u32 irq_status = readl(adc->regs + TGSR);
  387. +
  388. +   pr_debug("%s %X\n", __func__, irq_status);
  389. +   /* what source calls us? */
  390. +   if (irq_status & TGSR_TCQINT) {
  391. +       /* touch screen unit */
  392. +       if (adc->ts == NULL) {
  393. +           /* no consumer, bogus event */
  394. +           /* TODO */
  395. +       } else
  396. +           ts_ret = adc->ts_irq(adc->ts);
  397. +   }
  398. +
  399. +   if (irq_status & TGSR_GCQINT) {
  400. +       /* hwmon unit */
  401. +       if (adc->hwmon == NULL) {
  402. +           /* no consumer, bogus event */
  403. +           /* TODO */
  404. +       } else
  405. +           hwmon_ret = adc->hwmon_irq(adc->hwmon);
  406. +   }
  407. +
  408. +   if ((ts_ret == IRQ_NONE) && (hwmon_ret == IRQ_NONE)) {
  409. +       pr_warn("Event happens without a source\n");
  410. +       return IRQ_NONE;
  411. +   }
  412. +
  413. +   return IRQ_HANDLED;
  414. +}
  415. +
  416. +static void __devinit mxc_adc_setup_clock(struct imx_adc_device *adc)
  417. +{
  418. +   struct device *dev = &adc->pdev->dev;
  419. +   unsigned long inp_freq, adc_freq;
  420. +   unsigned div;
  421. +   u32 reg;
  422. +
  423. +   /* enable the unit's clock first */
  424. +   mxc_adc_enable_clk(adc);
  425. +
  426. +   inp_freq = clk_get_rate(adc->clk);
  427. +   div = DIV_ROUND_UP(inp_freq, adc->adc_freq);
  428. +   if (div < 10) {
  429. +       dev_warn(dev, "Clock @%lu Hz exceeds possible value."
  430. +           " Adjusted to %lu Hz\n", inp_freq / div, inp_freq / 10);
  431. +       div = 10;
  432. +   }
  433. +
  434. +   div -= 2;
  435. +   div = DIV_ROUND_UP(div, 2);
  436. +   adc_freq = inp_freq / (2 * div + 2);
  437. +
  438. +   reg = readl(adc->regs + TGCR) & ~TGCR_CLKCFG_MASK;
  439. +   writel(reg | TGCR_SET_CLKCFG(div), adc->regs + TGCR);
  440. +
  441. +   adc->adc_period = 1000000000L / adc_freq;
  442. +   dev_dbg(dev, "Clock setup to %lu Hz\n", adc_freq);
  443. +}
  444. +
  445. +static int __devinit mxc_adc_probe_dt(struct imx_adc_device *adc,
  446. +                       struct platform_device *pdev)
  447. +{
  448. +   /* TODO */
  449. +   return -ENODEV;
  450. +}
  451. +
  452. +static int __devinit mxc_adc_probe_pdata(struct imx_adc_device *adc,
  453. +                       struct platform_device *pdev)
  454. +{
  455. +   struct imx_adc_platform_data *pdata = pdev->dev.platform_data;
  456. +   struct device *dev = &pdev->dev;
  457. +
  458. +   if (pdata == NULL) {
  459. +       dev_err(dev, "No platform data given. Cannot continue\n");
  460. +       return -EINVAL;
  461. +   }
  462. +
  463. +   adc->adc_freq = pdata->adc_freq;
  464. +
  465. +   if (adc->adc_freq > 1750000) {
  466. +       dev_warn(dev, "Clock @%lu Hz exceeds spec. Limited to 1.75 MHz\n",
  467. +                   pdata->adc_freq);
  468. +       adc->adc_freq = 1750000;
  469. +   }
  470. +
  471. +   if (adc->adc_freq == 0) {
  472. +       dev_warn(dev, "No run time clock given. Assuming 1.75 MHz\n");
  473. +       adc->adc_freq = 1750000;
  474. +   }
  475. +
  476. +   return 0;
  477. +}
  478. +
  479. +static int __devinit mxc_adc_probe(struct platform_device *pdev)
  480. +{
  481. +   struct device *dev = &pdev->dev;
  482. +   struct resource *res;
  483. +   int ret;
  484. +
  485. +   adc = kzalloc(sizeof(struct imx_adc_device), GFP_KERNEL);
  486. +   if (adc == NULL) {
  487. +       dev_err(dev, "failed to allocate imx_adc_device\n");
  488. +       return -ENOMEM;
  489. +   }
  490. +
  491. +   ret = mxc_adc_probe_dt(adc, pdev);
  492. +   if (ret == -ENODEV)
  493. +       mxc_adc_probe_pdata(adc, pdev);
  494. +
  495. +   res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  496. +   if (res == NULL) {
  497. +       dev_err(dev, "No ADC base address given\n");
  498. +       ret = -ENXIO;
  499. +       goto err_out0;
  500. +   }
  501. +
  502. +   adc->irq = platform_get_irq(pdev, 0);
  503. +   if (adc->irq <= 0) {
  504. +       dev_err(dev, "failed to get ADC's irq\n");
  505. +       ret = -ENOENT;
  506. +       goto err_out0;
  507. +   }
  508. +
  509. +   if (!request_mem_region(res->start, resource_size(res), DRIVER_NAME)) {
  510. +       dev_err(dev, "ADC seems already in use\n");
  511. +       ret = -EBUSY;
  512. +       goto err_out0;
  513. +   }
  514. +
  515. +   adc->regs = ioremap(res->start, resource_size(res));
  516. +   if (adc->regs == NULL) {
  517. +       dev_err(dev, "failed to map ADC registers\n");
  518. +       ret = -ENXIO;
  519. +       goto err_region;
  520. +   }
  521. +
  522. +   ret = request_irq(adc->irq, mxc_adc_irq, 0, dev_name(dev), adc);
  523. +   if (ret < 0) {
  524. +       dev_err(dev, "failed to claim ADC's irq\n");
  525. +       goto err_ioremap;
  526. +   }
  527. +
  528. +   adc->clk = clk_get(dev, NULL);
  529. +   if (IS_ERR(adc->clk)) {
  530. +       dev_err(dev, "failed to get ADC's clock\n");
  531. +       ret = PTR_ERR(adc->clk);
  532. +       goto err_irq;
  533. +   }
  534. +
  535. +   adc->pdev = pdev;
  536. +
  537. +   mxc_adc_setup_clock(adc);
  538. +
  539. +   dev_info(dev, "Up and running\n");
  540. +   return 0;
  541. +
  542. +err_irq:
  543. +   free_irq(adc->irq, adc);
  544. +err_ioremap:
  545. +   iounmap(adc->regs);
  546. +err_region:
  547. +   release_mem_region(res->start, resource_size(res));
  548. +err_out0:
  549. +   kfree(adc);
  550. +   return ret;
  551. +}
  552. +
  553. +static int __devexit mxc_adc_remove(struct platform_device *pdev)
  554. +{
  555. +   struct imx_adc_device *adc = platform_get_drvdata(pdev);
  556. +   struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  557. +
  558. +   mxc_adc_reset(adc);
  559. +   free_irq(adc->irq, adc);
  560. +   mxc_adc_disable_clk(adc);
  561. +   iounmap(adc->regs);
  562. +   release_mem_region(res->start, resource_size(res));
  563. +   clk_put(adc->clk);
  564. +   kfree(adc);
  565. +
  566. +   return 0;
  567. +}
  568. +
  569. +static int __maybe_unused mxc_adc_suspend(struct device *dev)
  570. +{
  571. +   struct platform_device *pdev =
  572. +               container_of(dev, struct platform_device, dev);
  573. +   struct imx_adc_device *adc = platform_get_drvdata(pdev);
  574. +   u32 reg;
  575. +
  576. +   /* TODO */
  577. +   return 0;
  578. +}
  579. +
  580. +static int __maybe_unused mxc_adc_resume(struct device *dev)
  581. +{
  582. +   struct platform_device *pdev =
  583. +               container_of(dev, struct platform_device, dev);
  584. +   struct imx_adc_device *adc = platform_get_drvdata(pdev);
  585. +   u32 reg;
  586. +
  587. +   /* TODO */
  588. +
  589. +   return 0;
  590. +}
  591. +
  592. +static const struct dev_pm_ops adc_pm_ops = {
  593. +#ifdef CONFIG_PM
  594. +   .suspend    = mxc_adc_suspend,
  595. +   .resume     = mxc_adc_resume,
  596. +#endif
  597. +};
  598. +
  599. +static struct platform_driver mxc_adc_driver = {
  600. +   .driver     = {
  601. +       .name   = DRIVER_NAME,
  602. +       .owner  = THIS_MODULE,
  603. +       .pm = &adc_pm_ops,
  604. +   },
  605. +   .probe      = mxc_adc_probe,
  606. +   .remove     = __devexit_p(mxc_adc_remove),
  607. +};
  608. +
  609. +static int __init mxc_adc_init(void)
  610. +{
  611. +   int ret;
  612. +
  613. +   ret = platform_driver_register(&mxc_adc_driver);
  614. +   if (ret)
  615. +       pr_err("%s: failed to add adc driver\n", __func__);
  616. +
  617. +   return ret;
  618. +}
  619. +
  620. +module_init(mxc_adc_init);
  621. diff --git a/arch/arm/plat-mxc/devices/Makefile b/arch/arm/plat-mxc/devices/Makefile
  622. index c11ac84..ee7cdaf 100644
  623. --- a/arch/arm/plat-mxc/devices/Makefile
  624. +++ b/arch/arm/plat-mxc/devices/Makefile
  625. @@ -24,6 +24,7 @@ obj-$(CONFIG_IMX_HAVE_PLATFORM_MXC_PWM) += platform-mxc_pwm.o
  626.  obj-$(CONFIG_IMX_HAVE_PLATFORM_MXC_RNGA) += platform-mxc_rnga.o
  627.  obj-$(CONFIG_IMX_HAVE_PLATFORM_MXC_RTC) += platform-mxc_rtc.o
  628.  obj-$(CONFIG_IMX_HAVE_PLATFORM_MXC_W1) += platform-mxc_w1.o
  629. +obj-$(CONFIG_IMX_HAVE_ADC_V1) += platform-imx-adc.o
  630.  obj-$(CONFIG_IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX) += platform-sdhci-esdhc-imx.o
  631.  obj-$(CONFIG_IMX_HAVE_PLATFORM_SPI_IMX) +=  platform-spi_imx.o
  632.  obj-$(CONFIG_IMX_HAVE_PLATFORM_AHCI) +=  platform-ahci-imx.o
  633. diff --git a/arch/arm/plat-mxc/devices/platform-imx-adc.c b/arch/arm/plat-mxc/devices/platform-imx-adc.c
  634. new file mode 100644
  635. index 0000000..a57a7ba
  636. --- /dev/null
  637. +++ b/arch/arm/plat-mxc/devices/platform-imx-adc.c
  638. @@ -0,0 +1,61 @@
  639. +/*
  640. + * Copyright (C) 2011 Pengutronix
  641. + * Juergen Beisert <kernel@pengutronix.de>
  642. + *
  643. + * This program is free software; you can redistribute it and/or modify it under
  644. + * the terms of the GNU General Public License version 2 as published by the
  645. + * Free Software Foundation.
  646. + */
  647. +#include <mach/hardware.h>
  648. +#include <mach/devices-common.h>
  649. +#include <linux/platform_data/imx-adc.h>
  650. +
  651. +#define imx_imx_adc_data_entry_single(soc, _size)  \
  652. +   .iobase = soc ## _ADC ## _BASE_ADDR,    \
  653. +   .iosize = _size,            \
  654. +   .irq = soc ## _INT_ADC
  655. +
  656. +#ifdef CONFIG_SOC_IMX25
  657. +const struct imx_imx_adc_data imx25_imx_adc_data __initconst = {
  658. +   imx_imx_adc_data_entry_single(MX25, SZ_16K),
  659. +};
  660. +#endif /* ifdef CONFIG_SOC_IMX25 */
  661. +
  662. +
  663. +struct platform_device *__init imx_add_imx_adc(
  664. +       const struct imx_imx_adc_data *data,
  665. +       const struct imx_adc_platform_data *adc_pdata,
  666. +       const struct imx_ts_platform_data *ts_pdata,
  667. +       const struct imx_hwmon_platform_data *hwmon_pdata)
  668. +{
  669. +   struct platform_device *adc_pdev, *ts_dev = NULL, *hwmon_dev = NULL;
  670. +   struct resource res[] = {
  671. +       {
  672. +           .start = data->iobase,
  673. +           .end = data->iobase + data->iosize - 1,
  674. +           .flags = IORESOURCE_MEM,
  675. +       }, {
  676. +           .start = data->irq,
  677. +           .end = data->irq,
  678. +           .flags = IORESOURCE_IRQ,
  679. +       },
  680. +   };
  681. +
  682. +   adc_pdev = imx_add_platform_device("mx25-adc", 0,
  683. +           res, ARRAY_SIZE(res),
  684. +           adc_pdata, sizeof(*adc_pdata));
  685. +
  686. +   if (ts_pdata != NULL) {
  687. +       ts_dev = imx_add_platform_device("mx25-ts", 0, NULL, 0,
  688. +           ts_pdata, sizeof(*ts_pdata));
  689. +       ts_dev->dev.parent = &adc_pdev->dev;
  690. +   }
  691. +
  692. +   if (hwmon_pdata != NULL) {
  693. +       hwmon_dev = imx_add_platform_device("mx25-hwmon", 0, NULL, 0,
  694. +           hwmon_pdata, sizeof(*hwmon_pdata));
  695. +       hwmon_dev->dev.parent = &adc_pdev->dev;
  696. +   }
  697. +
  698. +   return adc_pdev;
  699. +}
  700. diff --git a/arch/arm/plat-mxc/imx-hwmon.c b/arch/arm/plat-mxc/imx-hwmon.c
  701. new file mode 100644
  702. index 0000000..9427021
  703. --- /dev/null
  704. +++ b/arch/arm/plat-mxc/imx-hwmon.c
  705. @@ -0,0 +1,146 @@
  706. +/*
  707. + * Copyright (C) 2011 Juergen Beisert, Pengutronix <kernel@pengutronix.de>
  708. + *
  709. + * This software is licensed under the terms of the GNU General Public
  710. + * License version 2, as published by the Free Software Foundation, and
  711. + * may be copied, distributed, and modified under those terms.
  712. + *
  713. + * This program is distributed in the hope that it will be useful,
  714. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  715. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  716. + * GNU General Public License for more details.
  717. + *
  718. + */
  719. +#include <linux/kernel.h>
  720. +#include <linux/module.h>
  721. +#include <linux/platform_device.h>
  722. +#include <linux/slab.h>
  723. +#include <linux/io.h>
  724. +#include <linux/err.h>
  725. +#include <linux/platform_data/imx-adc.h>
  726. +
  727. +#include <mach/adc.h>
  728. +
  729. +#define GCQFIFO 0x800
  730. +#define GCQCR 0x804
  731. +#define GCQSR 0x808
  732. +#define GCQMR 0x80c
  733. +#define GCQITEM_L 0x820
  734. +#define GCQITEM_H 0x824
  735. +#define GCC0 0x840
  736. +#define GCC1 0x844
  737. +#define GCC2 0x848
  738. +#define GCC3 0x84c
  739. +#define GCC4 0x850
  740. +#define GCC5 0x854
  741. +#define GCC6 0x858
  742. +#define GCC7 0x85c
  743. +
  744. +struct imx_hwmon_device {
  745. +   struct platform_device *pdev;
  746. +   void *imx_adc;
  747. +   void __iomem *regs;
  748. +};
  749. +
  750. +static irqreturn_t mx25_hwmon_irq(void *p)
  751. +{
  752. +   struct imx_hwmon_device *hwmon = (struct imx_hwmon_device *)p;
  753. +
  754. +   return IRQ_NONE;
  755. +}
  756. +
  757. +static int __devinit imx_hwmon_probe(struct platform_device *pdev)
  758. +{
  759. +   struct imx_hwmon_platform_data *pdata = pdev->dev.platform_data;
  760. +   struct device *dev = &pdev->dev;
  761. +   struct imx_hwmon_device *hwmon;
  762. +   int rc;
  763. +
  764. +   if (pdata == NULL) {
  765. +       dev_err(dev, "No platform data given. Cannot continue\n");
  766. +       return -EINVAL;
  767. +   }
  768. +
  769. +   hwmon = kzalloc(sizeof(struct imx_hwmon_device), GFP_KERNEL);
  770. +   if (hwmon == NULL) {
  771. +       dev_err(dev, "failed to allocate imx_hwmon_device\n");
  772. +       return -ENOMEM;
  773. +   }
  774. +
  775. +   hwmon->imx_adc = imx_adc_register_hwmon(hwmon, mx25_hwmon_irq);
  776. +   if (IS_ERR(hwmon->imx_adc)) {
  777. +       dev_err(dev, "Cannot conntect to ADC main driver\n");
  778. +       rc = PTR_ERR(hwmon->imx_adc);
  779. +       goto on_register_error;
  780. +   }
  781. +
  782. +   hwmon->regs = imx_adc_get_iomem(hwmon->imx_adc);
  783. +
  784. +   platform_set_drvdata(pdev, hwmon);
  785. +
  786. +   return 0;
  787. +
  788. +on_input_dev_error:
  789. +   imx_adc_put_iomem(hwmon->regs, hwmon->imx_adc);
  790. +   imx_adc_unregister_hwmon(hwmon->imx_adc, hwmon);
  791. +on_register_error:
  792. +   kfree(hwmon);
  793. +   return rc;
  794. +}
  795. +
  796. +static int __devexit imx_hwmon_remove(struct platform_device *pdev)
  797. +{
  798. +   struct imx_hwmon_device *hwmon = platform_get_drvdata(pdev);
  799. +
  800. +   imx_adc_put_iomem(hwmon->regs, hwmon->imx_adc);
  801. +   imx_adc_unregister_hwmon(hwmon->imx_adc, hwmon);
  802. +   kfree(hwmon);
  803. +   platform_set_drvdata(pdev, NULL);
  804. +
  805. +   return 0;
  806. +}
  807. +
  808. +static int __maybe_unused imx_hwmon_suspend(struct device *dev)
  809. +{
  810. +   struct platform_device *pdev = container_of(dev, struct platform_device, dev);
  811. +   struct imx_hwmon_device *hwmon = platform_get_drvdata(pdev);
  812. +
  813. +   return 0;
  814. +}
  815. +
  816. +static int __maybe_unused imx_hwmon_resume(struct device *dev)
  817. +{
  818. +   struct platform_device *pdev = container_of(dev, struct platform_device, dev);
  819. +   struct imx_hwmon_device *hwmon = platform_get_drvdata(pdev);
  820. +
  821. +   return 0;
  822. +}
  823. +
  824. +static const struct dev_pm_ops hwmon_pm_ops = {
  825. +#ifdef CONFIG_PM
  826. +   .suspend = imx_hwmon_suspend,
  827. +   .resume = imx_hwmon_resume,
  828. +#endif
  829. +};
  830. +
  831. +static struct platform_driver imx_hwmon_driver = {
  832. +   .driver = {
  833. +       .name = "imx-hwmon",
  834. +       .owner = THIS_MODULE,
  835. +       .pm = &hwmon_pm_ops,
  836. +   },
  837. +   .probe = imx_hwmon_probe,
  838. +   .remove = __devexit_p(imx_hwmon_remove),
  839. +};
  840. +
  841. +static int __init imx_hwmon_init(void)
  842. +{
  843. +   int ret;
  844. +
  845. +   ret = platform_driver_register(&imx_hwmon_driver);
  846. +   if (ret)
  847. +       pr_err("%s: failed to add hwmon driver\n", __func__);
  848. +   return ret;
  849. +}
  850. +
  851. +module_init(imx_hwmon_init);
  852. diff --git a/arch/arm/plat-mxc/imx-ts.c b/arch/arm/plat-mxc/imx-ts.c
  853. new file mode 100644
  854. index 0000000..4dcad9b
  855. --- /dev/null
  856. +++ b/arch/arm/plat-mxc/imx-ts.c
  857. @@ -0,0 +1,749 @@
  858. +/*
  859. + * Copyright (C) 2011 Juergen Beisert, Pengutronix <kernel@pengutronix.de>
  860. + *
  861. + * This software is licensed under the terms of the GNU General Public
  862. + * License version 2, as published by the Free Software Foundation, and
  863. + * may be copied, distributed, and modified under those terms.
  864. + *
  865. + * This program is distributed in the hope that it will be useful,
  866. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  867. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  868. + * GNU General Public License for more details.
  869. + *
  870. + */
  871. +#undef DEBUG
  872. +
  873. +#include <linux/kernel.h>
  874. +#include <linux/module.h>
  875. +#include <linux/platform_device.h>
  876. +#include <linux/input.h>
  877. +#include <linux/slab.h>
  878. +#include <linux/io.h>
  879. +#include <linux/workqueue.h>
  880. +#include <linux/platform_data/imx-adc.h>
  881. +
  882. +#include <mach/adc.h>
  883. +
  884. +#define TCQFIFO 0x400
  885. +# define TCQFIFO_TO_INDEX(x) ((x) & 0x0f)
  886. +# define TCQFIFO_TO_VAL(x) ((x) >> 4)
  887. +
  888. +#define TCQCR 0x404
  889. +# define TCQCR_LAST_ITEM_MASK 0xf0
  890. +# define TCQCR_LAST_ITEM(x) ((x) << 4)
  891. +# define TCQCR_QSM_MASK 0x3
  892. +# define TCQCR_QSM_STOP 0x0
  893. +# define TCQCR_QSM_PD (1 << 0)
  894. +# define TCQCR_QSM_FQS (1 << 1)
  895. +# define TCQCR_FQS (1 << 2)
  896. +# define TCQCR_RPT (1 << 3)
  897. +# define TCQCR_WATERMARK(x) ((x) << 8)
  898. +# define TCQCR_REPEATWAIT(x) ((x) << 12)
  899. +# define TCQCR_QRST (1 << 16)
  900. +# define TCQCR_FRST (1 << 17)
  901. +# define TCQCR_PD_MSK (1 << 18)
  902. +# define TCQCR_PD_CFG (1 << 19)
  903. +
  904. +#define TCQSR 0x408
  905. +# define TCQSR_PD (1 << 0)
  906. +# define TCQSR_EOQ (1 << 1)
  907. +# define TCQSR_FOR (1 << 4)
  908. +# define TCQSR_FUR (1 << 5)
  909. +# define TCQSR_FRR (1 << 6)
  910. +# define TCQSR_EMPT (1 << 13)
  911. +# define TCQSR_FDRY (1 << 15)
  912. +
  913. +#define TCQMR 0x40c
  914. +# define TCQMR_PD_IRQ_MSK (1 << 0)
  915. +# define TCQMR_EOQ_IRQ_MSK (1 << 1)
  916. +# define TCQMR_FDRY_MSK (1 << 15)
  917. +
  918. +#define TCQITEM_L 0x420
  919. +# define TCQ_ITEM0(x) (x)
  920. +# define TCQ_ITEM1(x) ((x) << 4)
  921. +# define TCQ_ITEM2(x) ((x) << 8)
  922. +# define TCQ_ITEM3(x) ((x) << 12)
  923. +# define TCQ_ITEM4(x) ((x) << 16)
  924. +# define TCQ_ITEM5(x) ((x) << 20)
  925. +# define TCQ_ITEM6(x) ((x) << 24)
  926. +# define TCQ_ITEM7(x) ((x) << 28)
  927. +#  define ITEM_TCC0 0
  928. +#  define ITEM_TCC1 1
  929. +#  define ITEM_TCC2 2
  930. +#  define ITEM_TCC3 3
  931. +#  define ITEM_TCC4 4
  932. +#  define ITEM_TCC5 5
  933. +
  934. +#define TCQITEM_U 0x424
  935. +#define TCC0 0x440
  936. +#define TCC1 0x444
  937. +#define TCC2 0x448
  938. +#define TCC3 0x44c
  939. +#define TCC4 0x450
  940. +#define TCC5 0x454
  941. +#define TCC6 0x458
  942. +#define TCC7 0x45c
  943. +
  944. +#define TCC_SETTLING_TIME(x) ((x) << 24)
  945. +#define TCC_IGS (1 << 20)
  946. +#define TCC_NOS(x) ((x) << 16)
  947. +
  948. +#define TCC_WIPERSW_ON (1 << 15)
  949. +#define TCC_WIPERSW_OFF (0 << 15)
  950. +
  951. +#define TCC_YNLRSW_L (1 << 14)
  952. +#define TCC_YNLRSW_OFF (0 << 14)
  953. +
  954. +#define TCC_YPLLSW_H (0 << 12)
  955. +#define TCC_YPLLSW_OFF (1 << 12)
  956. +#define TCC_YPLLSW_L (3 << 12)
  957. +
  958. +#define TCC_XNURSW_H (0 << 10)
  959. +#define TCC_XNURSW_OFF (1 << 10)
  960. +#define TCC_XNURSW_L (3 << 10)
  961. +
  962. +#define TCC_XPULSW_H (0 << 9)
  963. +#define TCC_XPULSW_OFF (1 << 9)
  964. +
  965. +#define TCC_SELREFP_YPLL (0 << 7)
  966. +#define TCC_SELREFP_XPUL (1 << 7)
  967. +#define TCC_SELREFP_EXT_REF (2 << 7)
  968. +#define TCC_SELREFP_INT_REF (3 << 7)
  969. +
  970. +#define TCC_SELIN_XPUL (0 << 4)
  971. +#define TCC_SELIN_YPLL (1 << 4)
  972. +#define TCC_SELIN_XNUR (2 << 4)
  973. +#define TCC_SELIN_YNLR (3 << 4)
  974. +#define TCC_SELIN_WIPER (4 << 4)
  975. +#define TCC_SELIN_INAUX0 (5 << 4)
  976. +#define TCC_SELIN_INAUX1 (6 << 4)
  977. +#define TCC_SELIN_INAUX2 (7 << 4)
  978. +
  979. +#define TCC_SELREFN_XNUR (0 << 2)
  980. +#define TCC_SELREFN_YNLR (1 << 2)
  981. +#define TCC_SELREFN_AGND1 (2 << 2)
  982. +#define TCC_SELREFN_AGND2 (3 << 2)
  983. +
  984. +#define TCC_PENIACK (1 << 1)
  985. +
  986. +/*
  987. + * Y+ off
  988. + * Y- off
  989. + * X+ high (with low impedance) <-- ADC in
  990. + * X- off
  991. + * ADC in single-ended measurement topology
  992. + */
  993. +#define TSC_4WIRE_PRECHARGE (TCC_WIPERSW_OFF | TCC_YNLRSW_OFF | \
  994. +       TCC_YPLLSW_OFF | TCC_XNURSW_OFF | TCC_XPULSW_H | \
  995. +       TCC_SELREFP_INT_REF | TCC_SELIN_XPUL | TCC_SELREFN_AGND2)
  996. +
  997. +/*
  998. + * Y+ low
  999. + * Y- low
  1000. + * X+ off <-- ADC in
  1001. + * X- off
  1002. + * ADC in single-ended measurement topology
  1003. + *
  1004. + * 'TCC_PENIACK' enables a weak pull up at the X+ signal
  1005. + */
  1006. +#define TSC_4WIRE_TOUCH_DETECT (TCC_WIPERSW_OFF | TCC_YNLRSW_L | \
  1007. +       TCC_YPLLSW_L | TCC_XNURSW_OFF | TCC_XPULSW_OFF | \
  1008. +       TCC_SELREFP_INT_REF | TCC_SELIN_XPUL | TCC_SELREFN_AGND2 | \
  1009. +       TCC_PENIACK)
  1010. +
  1011. +/*
  1012. + * Y+ off <-- ADC in
  1013. + * Y- off
  1014. + * X+ high <- high ADC ref
  1015. + * X- low  <- low ADC ref
  1016. + * ADC in differential measurement topology
  1017. + */
  1018. +#define TSC_4WIRE_X_MEASUMENT (TCC_WIPERSW_OFF | TCC_YNLRSW_OFF | \
  1019. +       TCC_YPLLSW_OFF | TCC_XNURSW_L | TCC_XPULSW_H | \
  1020. +       TCC_SELREFP_XPUL | TCC_SELIN_YPLL | TCC_SELREFN_XNUR)
  1021. +
  1022. +/*
  1023. + * Y+ high <- high ADC ref
  1024. + * Y- low <- low ADC ref
  1025. + * X+ off <-- ADC in
  1026. + * X- off
  1027. + * ADC in differential measurement topology
  1028. + */
  1029. +#define TSC_4WIRE_Y_MEASUMENT (TCC_WIPERSW_OFF | TCC_YNLRSW_L | \
  1030. +       TCC_YPLLSW_H | TCC_XNURSW_OFF | TCC_XPULSW_OFF | \
  1031. +       TCC_SELREFP_YPLL | TCC_SELIN_XPUL | TCC_SELREFN_YNLR)
  1032. +
  1033. +/*
  1034. + * Pressure measurement (1/2)
  1035. + * Y+ high
  1036. + * Y- off
  1037. + * X+ off <-- ADC in
  1038. + * X- low
  1039. + * ADC in single-ended measurement topology
  1040. + */
  1041. +#define TSC_4WIRE_XP_MEASUMENT (TCC_WIPERSW_OFF | TCC_YNLRSW_OFF | \
  1042. +       TCC_YPLLSW_H | TCC_XNURSW_L | TCC_XPULSW_OFF | \
  1043. +       TCC_SELREFP_INT_REF | TCC_SELIN_XPUL | TCC_SELREFN_AGND2)
  1044. +
  1045. +/*
  1046. + * Pressure measurement (2/2)
  1047. + * Y+ high
  1048. + * Y- off <-- ADC in
  1049. + * X+ off
  1050. + * X- low
  1051. + * ADC in single-ended measurement topology
  1052. + */
  1053. +#define TSC_4WIRE_YN_MEASUMENT (TCC_WIPERSW_OFF | TCC_YNLRSW_OFF | \
  1054. +       TCC_YPLLSW_H | TCC_XNURSW_L | TCC_XPULSW_OFF | \
  1055. +       TCC_SELREFP_INT_REF | TCC_SELIN_YNLR | TCC_SELREFN_AGND2)
  1056. +
  1057. +struct imx_ts_device {
  1058. +   struct platform_device *pdev;
  1059. +   struct input_dev *input;
  1060. +   void *imx_adc;
  1061. +   void __iomem *regs;
  1062. +
  1063. +   struct work_struct work;
  1064. +
  1065. +   /* accquisition settings */
  1066. +   unsigned pen_debounce;  /* [us] */
  1067. +   unsigned pen_treshold;
  1068. +   unsigned repeat_wait;   /* [us] */
  1069. +   unsigned settling_time; /* [us] */
  1070. +   unsigned sample_cnt;
  1071. +   unsigned in_sync;   /* noise reduction settings */
  1072. +   /* touchscreen settings */
  1073. +   unsigned last_queue_item;
  1074. +   unsigned expected_samples;
  1075. +   unsigned avail_samples;
  1076. +   u32 sample_buf[16];
  1077. +};
  1078. +
  1079. +static void imx_tsc_fill_state(struct imx_ts_device *ts, int state, u32 val)
  1080. +{
  1081. +   writel(val, ts->regs + TCC0 + state * 4);
  1082. +   pr_debug("%s: filling state %d with %08X\n", __func__, state, val);
  1083. +}
  1084. +
  1085. +/* four wire measure protocol */
  1086. +#define TSC_4WIRE_PRE_INDEX ITEM_TCC0
  1087. +#define TSC_4WIRE_X_INDEX ITEM_TCC1
  1088. +#define TSC_4WIRE_Y_INDEX ITEM_TCC2
  1089. +#define TSC_4WIRE_POST_INDEX ITEM_TCC3
  1090. +#define TSC_4WIRE_LEAVE ITEM_TCC4
  1091. +
  1092. +static int imx_prepare_for_4wire(struct imx_ts_device *ts,
  1093. +                       unsigned settling_time)
  1094. +{
  1095. +   /*
  1096. +    * What should be done in the queue?
  1097. +    * - touch meas
  1098. +    * - x meas
  1099. +    * - y meas
  1100. +    * - touch detect
  1101. +    */
  1102. +
  1103. +   /* for a propper touch detection, preload the X plane */
  1104. +   writel(TSC_4WIRE_PRECHARGE | TCC_IGS, ts->regs + TICR);
  1105. +
  1106. +   /* we need always a sample to check if this event is valid */
  1107. +   imx_tsc_fill_state(ts, TSC_4WIRE_PRE_INDEX, TSC_4WIRE_TOUCH_DETECT |
  1108. +               TCC_NOS(0) |    /* one sample */
  1109. +               TCC_SETTLING_TIME(settling_time));
  1110. +   /* measure X coordinate */
  1111. +   imx_tsc_fill_state(ts, TSC_4WIRE_X_INDEX, TSC_4WIRE_X_MEASUMENT |
  1112. +               TCC_NOS(ts->sample_cnt - 1) |
  1113. +               TCC_SETTLING_TIME(settling_time));
  1114. +   /* measure Y corrdinate */
  1115. +   imx_tsc_fill_state(ts, TSC_4WIRE_Y_INDEX, TSC_4WIRE_Y_MEASUMENT |
  1116. +               TCC_NOS(ts->sample_cnt - 1) |
  1117. +               TCC_SETTLING_TIME(settling_time));
  1118. +   /* we need always a sample to check if this event is valid */
  1119. +   imx_tsc_fill_state(ts, TSC_4WIRE_POST_INDEX, TSC_4WIRE_TOUCH_DETECT |
  1120. +               TCC_NOS(0) |    /* one sample */
  1121. +               TCC_SETTLING_TIME(settling_time));
  1122. +   /* leave the touchscreen in detection configuration */
  1123. +   imx_tsc_fill_state(ts, TSC_4WIRE_LEAVE, TSC_4WIRE_TOUCH_DETECT |
  1124. +               TCC_IGS | TCC_SETTLING_TIME(settling_time));
  1125. +
  1126. +   /*
  1127. +    * In which order these items have to be done
  1128. +    * touch meas -> x meas -> y meas -> touch meas -> touch detect
  1129. +    */
  1130. +   writel(TCQ_ITEM0(TSC_4WIRE_PRE_INDEX) |
  1131. +           TCQ_ITEM1(TSC_4WIRE_X_INDEX) |
  1132. +       TCQ_ITEM2(TSC_4WIRE_Y_INDEX) |
  1133. +       TCQ_ITEM3(TSC_4WIRE_POST_INDEX) |
  1134. +       TCQ_ITEM4(TSC_4WIRE_LEAVE),
  1135. +       ts->regs + TCQITEM_L);
  1136. +
  1137. +   ts->expected_samples = ts->sample_cnt + ts->sample_cnt + 1 + 1;
  1138. +   ts->last_queue_item = 4;
  1139. +
  1140. +   /* Enable the touch detection right now */
  1141. +   writel(TSC_4WIRE_TOUCH_DETECT | TCC_IGS, ts->regs + TICR);
  1142. +
  1143. +   return 0;
  1144. +}
  1145. +
  1146. +static void imx_disable_touch_irq(struct imx_ts_device *ts)
  1147. +{
  1148. +   u32 tcqcr;
  1149. +
  1150. +   tcqcr = readl(ts->regs + TCQCR);
  1151. +   writel(tcqcr | TCQCR_PD_MSK, ts->regs + TCQCR);
  1152. +}
  1153. +
  1154. +static void imx_enable_touch_irq(struct imx_ts_device *ts)
  1155. +{
  1156. +   u32 tcqcr;
  1157. +
  1158. +   tcqcr = readl(ts->regs + TCQCR);
  1159. +   writel(tcqcr & ~TCQCR_PD_MSK, ts->regs + TCQCR);
  1160. +}
  1161. +
  1162. +static void imx_disable_fifo_irq(struct imx_ts_device *ts)
  1163. +{
  1164. +   u32 tcqmr;
  1165. +
  1166. +   tcqmr = readl(ts->regs + TCQMR);
  1167. +   writel(tcqmr | TCQMR_FDRY_MSK, ts->regs + TCQMR);
  1168. +}
  1169. +
  1170. +static void imx_enable_fifo_irq(struct imx_ts_device *ts)
  1171. +{
  1172. +   u32 tcqmr;
  1173. +
  1174. +   tcqmr = readl(ts->regs + TCQMR);
  1175. +   writel(tcqmr & ~TCQMR_FDRY_MSK, ts->regs + TCQMR);
  1176. +}
  1177. +
  1178. +/* fire the queue once */
  1179. +static void imx_force_queue_start(struct imx_ts_device *ts)
  1180. +{
  1181. +   u32 tcqcr;
  1182. +
  1183. +   tcqcr = readl(ts->regs + TCQCR);
  1184. +   writel(tcqcr | TCQCR_FQS, ts->regs + TCQCR);
  1185. +   /* clear the flag immediately, else the queue runs forever */
  1186. +   writel(tcqcr, ts->regs + TCQCR);
  1187. +}
  1188. +
  1189. +static void imx_force_queue_stop(struct imx_ts_device *ts)
  1190. +{
  1191. +   u32 tcqcr;
  1192. +
  1193. +   tcqcr = readl(ts->regs + TCQCR);
  1194. +   writel(tcqcr & ~TCQCR_FQS, ts->regs + TCQCR);
  1195. +}
  1196. +
  1197. +static void imx_fifo_reset(struct imx_ts_device *ts)
  1198. +{
  1199. +   u32 tcqcr;
  1200. +
  1201. +   tcqcr = readl(ts->regs + TCQCR);
  1202. +   writel(tcqcr | TCQCR_FRST, ts->regs + TCQCR);
  1203. +   writel(tcqcr, ts->regs + TCQCR);
  1204. +}
  1205. +
  1206. +static void imx_re_enable_touch_detection(struct imx_ts_device *ts)
  1207. +{
  1208. +   u32 tcqmr;
  1209. +
  1210. +   /* stop the queue from looping */
  1211. +   imx_force_queue_stop(ts);
  1212. +
  1213. +   /* for a clean touch detection, preload the X plane */
  1214. +   writel(TSC_4WIRE_PRECHARGE | TCC_IGS, ts->regs + TICR);
  1215. +
  1216. +   /* waste some time now to pre-load the X plate to high voltage */
  1217. +   imx_fifo_reset(ts);
  1218. +
  1219. +   /* re-enable the detection right now */
  1220. +   writel(TSC_4WIRE_TOUCH_DETECT | TCC_IGS, ts->regs + TICR);
  1221. +
  1222. +   writel(TCQSR_PD, ts->regs + TCQSR);
  1223. +
  1224. +   /* enable the pen down event to be a source for the interrupt */
  1225. +   tcqmr = readl(ts->regs + TCQMR);
  1226. +   writel(tcqmr & ~TCQMR_PD_IRQ_MSK, ts->regs + TCQMR);
  1227. +
  1228. +   /* lets fire the next IRQ if someone touches the touchscreen */
  1229. +   imx_enable_touch_irq(ts);
  1230. +}
  1231. +
  1232. +static int imx_create_event_for_4wire(struct imx_ts_device *ts)
  1233. +{
  1234. +   unsigned x_pos = 0, y_pos = 0, touch_pre = 0, touch_post = 0;
  1235. +   unsigned u, index, val;
  1236. +   int rc = 0;
  1237. +
  1238. +   for (u = 0; u < ts->avail_samples; u++) {
  1239. +       index = TCQFIFO_TO_INDEX(ts->sample_buf[u]);
  1240. +       val = TCQFIFO_TO_VAL(ts->sample_buf[u]);
  1241. +       switch (index) {
  1242. +       case TSC_4WIRE_PRE_INDEX:
  1243. +           touch_pre += val;
  1244. +           break;
  1245. +       case TSC_4WIRE_X_INDEX:
  1246. +           x_pos += val;
  1247. +           break;
  1248. +       case TSC_4WIRE_Y_INDEX:
  1249. +           y_pos += val;
  1250. +           break;
  1251. +       case TSC_4WIRE_POST_INDEX:
  1252. +           touch_post += val;
  1253. +           break;
  1254. +       default:
  1255. +           pr_err("Unknown index %u\n", index);
  1256. +           rc = -EINVAL;   /* TODO deadlock! */
  1257. +       }
  1258. +   }
  1259. +
  1260. +   if (rc == 0 && ts->avail_samples != 0) {
  1261. +       ts->avail_samples = 0;
  1262. +       /*
  1263. +        * only if both touch measures are below a treshold,
  1264. +        * the position is valid
  1265. +        */
  1266. +       if (touch_pre < ts->pen_treshold &&
  1267. +                   touch_post < ts->pen_treshold) {
  1268. +           /* valid samples, generate a report */
  1269. +           x_pos /= ts->sample_cnt;
  1270. +           y_pos /= ts->sample_cnt;
  1271. +           input_report_abs(ts->input, ABS_X, x_pos);
  1272. +           input_report_abs(ts->input, ABS_Y, y_pos);
  1273. +           input_report_key(ts->input, BTN_TOUCH,
  1274. +                   0xfff - ((touch_pre + touch_post) / 2));
  1275. +           input_sync(ts->input);
  1276. +
  1277. +           /* get next sample */
  1278. +           imx_force_queue_start(ts);
  1279. +           imx_enable_fifo_irq(ts);
  1280. +       } else {
  1281. +           if (touch_pre >= ts->pen_treshold &&
  1282. +                   touch_post >= ts->pen_treshold) {
  1283. +               /*
  1284. +                * if both samples are invalid,
  1285. +                * generate a release report
  1286. +                */
  1287. +               input_report_key(ts->input, BTN_TOUCH, 0);
  1288. +               input_sync(ts->input);
  1289. +               imx_re_enable_touch_detection(ts);
  1290. +           } else {
  1291. +               /*
  1292. +                * if only one of both touch measurements are
  1293. +                * below the threshold, still some bouncing
  1294. +                * happens. Take additional samples in this
  1295. +                * case to be sure
  1296. +                */
  1297. +               imx_force_queue_start(ts);
  1298. +               imx_enable_fifo_irq(ts);
  1299. +           }
  1300. +       }
  1301. +   }
  1302. +
  1303. +   return rc;
  1304. +}
  1305. +
  1306. +static void mx25_ts_workqueue(struct work_struct *work)
  1307. +{
  1308. +   struct imx_ts_device *ts = container_of(work, struct imx_ts_device, work);
  1309. +
  1310. +   /* read all samples */
  1311. +   while (!(readl(ts->regs + TCQSR) & TCQSR_EMPT)) {
  1312. +       if (ts->avail_samples < 16) {
  1313. +           ts->sample_buf[ts->avail_samples++] = readl(ts->regs + TCQFIFO);
  1314. +           pr_debug("- %04X", ts->sample_buf[ts->avail_samples - 1]);
  1315. +       } else {
  1316. +           pr_debug("!");
  1317. +           /* discard samples */
  1318. +           readl(ts->regs + TCQFIFO);
  1319. +       }
  1320. +   }
  1321. +   imx_create_event_for_4wire(ts);
  1322. +}
  1323. +
  1324. +/* ------------------------------------------------------------------------- */
  1325. +
  1326. +static irqreturn_t mx25_tsc_irq(void *p)
  1327. +{
  1328. +   struct imx_ts_device *ts = (struct imx_ts_device *)p;
  1329. +   u32 stat = readl(ts->regs + TCQSR);
  1330. +
  1331. +   pr_debug("%s: %08X\n", __func__, stat);
  1332. +
  1333. +   if (stat & (TCQSR_FRR | TCQSR_FUR | TCQSR_FOR)) {
  1334. +       pr_debug("%s: Resetting FIFO\n", __func__);
  1335. +       imx_fifo_reset(ts);
  1336. +       writel(stat & (TCQSR_FRR | TCQSR_FUR | TCQSR_FOR), ts->regs + TCQSR);
  1337. +   }
  1338. +
  1339. +   if (stat & TCQSR_PD) {
  1340. +       imx_disable_touch_irq(ts);
  1341. +       imx_force_queue_start(ts);
  1342. +       imx_enable_fifo_irq(ts);
  1343. +       writel(TCQSR_PD, ts->regs + TCQSR);
  1344. +   }
  1345. +
  1346. +   if (stat & TCQSR_EOQ) {
  1347. +       writel(TCQSR_EOQ, ts->regs + TCQSR);
  1348. +   }
  1349. +
  1350. +   if (stat & TCQSR_FDRY) {
  1351. +       imx_disable_fifo_irq(ts);
  1352. +       ts->avail_samples = 0;
  1353. +       schedule_work(&ts->work);
  1354. +   }
  1355. +
  1356. +   return IRQ_HANDLED;
  1357. +}
  1358. +
  1359. +/* configure the statemachine for a 4-wire touchscreen */
  1360. +static void __init imx_ts_init(struct imx_ts_device *ts)
  1361. +{
  1362. +   u32 tcqcr, in_sync = 0;
  1363. +   unsigned adc_period = imx_adc_get_period(ts->imx_adc);
  1364. +   unsigned repeat_wait = fls(DIV_ROUND_UP(ts->repeat_wait, adc_period));
  1365. +   unsigned debounce_cnt =
  1366. +           DIV_ROUND_UP(ts->pen_debounce, adc_period * 8) - 1;
  1367. +   unsigned settling_time = DIV_ROUND_UP(ts->settling_time, adc_period);
  1368. +
  1369. +   /* reset the logic first */
  1370. +   writel(TCQCR_QRST | TCQCR_FRST, ts->regs + TCQCR);
  1371. +
  1372. +   /* up to 128 * 8 ADC clocks are possible */
  1373. +   if (debounce_cnt > 127)
  1374. +       debounce_cnt = 127;
  1375. +
  1376. +   if (repeat_wait > 15)
  1377. +       repeat_wait = 15;
  1378. +
  1379. +   tcqcr = TCQCR_QSM_STOP |
  1380. +       TCQCR_REPEATWAIT(repeat_wait);
  1381. +   writel(tcqcr, ts->regs + TCQCR);
  1382. +
  1383. +   imx_prepare_for_4wire(ts, settling_time);
  1384. +
  1385. +   tcqcr |= TCQCR_LAST_ITEM(ts->last_queue_item - 1) |
  1386. +           TCQCR_WATERMARK(ts->expected_samples - 1);
  1387. +   writel(tcqcr, ts->regs + TCQCR);
  1388. +
  1389. +   pr_debug("%s: adc_period: %u ns, debounce_cnt: %u\n", __func__,
  1390. +                       adc_period, debounce_cnt);
  1391. +   pr_debug("%s: sample_count: %u, repeat_wait: %u\n", __func__,
  1392. +                   ts->expected_samples, repeat_wait);
  1393. +   pr_debug("%s: value for TCQITEM_L is: %X\n", __func__,
  1394. +                       readl(ts->regs + TCQITEM_L));
  1395. +
  1396. +   /* ensure for now all interrupt sources are disabled */
  1397. +   writel(0xffffffff, ts->regs + TCQMR);
  1398. +
  1399. +   switch (ts->in_sync) {
  1400. +   case MEAS_IF_LOW_HSYNC:
  1401. +       in_sync |= TGCR_HSYNCPOL; /* run the ADC while HYNC is low */
  1402. +   case MEAS_IF_HIG_HSYNC:
  1403. +       in_sync |= TGCR_HSYNCEN; /* enable this feature */
  1404. +       break;
  1405. +   }
  1406. +
  1407. +   /* setup ... */
  1408. +   imx_adc_ts_set_tgcr(ts->imx_adc, in_sync |
  1409. +                   TGCR_SET_PEN_DEBT(debounce_cnt));
  1410. +   /* ... and enable */
  1411. +   imx_adc_ts_set_tgcr(ts->imx_adc, in_sync |
  1412. +                   TGCR_SET_PEN_DEBT(debounce_cnt) |
  1413. +                   TGCR_PDBEN);
  1414. +   /* ... */
  1415. +   imx_adc_ts_set_tgcr(ts->imx_adc, in_sync |
  1416. +                   TGCR_SET_PEN_DEBT(debounce_cnt) |
  1417. +                   TGCR_PDBEN | TGCR_PDEN);
  1418. +
  1419. +   /* enable the engine on demand */
  1420. +   tcqcr |= TCQCR_QSM_FQS;
  1421. +   writel(tcqcr, ts->regs + TCQCR);
  1422. +
  1423. +   imx_re_enable_touch_detection(ts);
  1424. +}
  1425. +
  1426. +static int __devinit imx_ts_register_input_dev(struct imx_ts_device *ts)
  1427. +{
  1428. +   struct device *dev = &ts->pdev->dev;
  1429. +
  1430. +   ts->input = input_allocate_device();
  1431. +   if (ts->input == NULL) {
  1432. +       dev_err(dev, "Unable to allocate the input device !!\n");
  1433. +       return -ENOMEM;
  1434. +   }
  1435. +
  1436. +   ts->input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
  1437. +   ts->input->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
  1438. +   input_set_abs_params(ts->input, ABS_X, 0, 0xfff, 0, 0);
  1439. +   input_set_abs_params(ts->input, ABS_Y, 0, 0xfff, 0, 0);
  1440. +
  1441. +   ts->input->name = "mx25 ts";
  1442. +   ts->input->id.bustype = BUS_HOST;
  1443. +   ts->input->id.vendor = 0xDEAD;
  1444. +   ts->input->id.product = 0xBEEF;
  1445. +   ts->input->id.version = 0x0101;
  1446. +
  1447. +   if (input_register_device(ts->input) < 0) {
  1448. +       dev_err(dev, "failed to register input device\n");
  1449. +       input_free_device(ts->input);
  1450. +       return -EIO;
  1451. +   }
  1452. +
  1453. +   return 0;
  1454. +}
  1455. +
  1456. +/* TODO add device tree support */
  1457. +static int __devinit mx25_ts_probe_dt(struct imx_ts_device *ts,
  1458. +                       struct platform_device *pdev)
  1459. +{
  1460. +   return -ENODEV;
  1461. +}
  1462. +
  1463. +static int __devinit mx25_ts_probe_pdata(struct imx_ts_device *ts,
  1464. +                       struct platform_device *pdev)
  1465. +{
  1466. +   struct imx_ts_platform_data *pdata = pdev->dev.platform_data;
  1467. +   struct device *dev = &pdev->dev;
  1468. +
  1469. +   if (pdata == NULL) {
  1470. +       dev_err(dev, "No platform data given. Cannot continue\n");
  1471. +       return -EINVAL;
  1472. +   }
  1473. +
  1474. +   ts->pen_debounce = pdata->pen_debounce;
  1475. +   ts->repeat_wait = pdata->repeat_wait;
  1476. +   ts->settling_time = pdata->settling_time;
  1477. +   ts->sample_cnt = pdata->sample_cnt;
  1478. +   ts->pen_treshold = pdata->pen_treshold;
  1479. +   ts->in_sync = pdata->in_sync;
  1480. +
  1481. +   if (ts->pen_treshold == 0)
  1482. +       ts->pen_treshold = 256;
  1483. +
  1484. +   if (ts->sample_cnt == 0)
  1485. +       ts->sample_cnt = 1;
  1486. +
  1487. +   return 0;
  1488. +}
  1489. +
  1490. +static int __devinit imx_ts_probe(struct platform_device *pdev)
  1491. +{
  1492. +   struct device *dev = &pdev->dev;
  1493. +   struct imx_ts_device *ts;
  1494. +   int rc;
  1495. +
  1496. +   ts = kzalloc(sizeof(struct imx_ts_device), GFP_KERNEL);
  1497. +   if (ts == NULL) {
  1498. +       dev_err(dev, "failed to allocate imx_ts_device\n");
  1499. +       return -ENOMEM;
  1500. +   }
  1501. +
  1502. +   ts->pdev = pdev;
  1503. +
  1504. +   rc = mx25_ts_probe_dt(ts, pdev);
  1505. +   if (rc == -ENODEV)
  1506. +       mx25_ts_probe_pdata(ts, pdev);
  1507. +
  1508. +   ts->imx_adc = imx_adc_register_ts(ts, mx25_tsc_irq);
  1509. +   if (IS_ERR(ts->imx_adc)) {
  1510. +       dev_err(dev, "Cannot conntect to ADC main driver\n");
  1511. +       rc = PTR_ERR(ts->imx_adc);
  1512. +       goto on_register_error;
  1513. +   }
  1514. +
  1515. +   ts->regs = imx_adc_get_iomem(ts->imx_adc);
  1516. +
  1517. +   INIT_WORK(&ts->work, mx25_ts_workqueue);
  1518. +
  1519. +   imx_ts_init(ts);
  1520. +
  1521. +   rc = imx_ts_register_input_dev(ts);
  1522. +   if (rc < 0)
  1523. +       goto on_input_dev_error;
  1524. +
  1525. +   platform_set_drvdata(pdev, ts);
  1526. +
  1527. +   return 0;
  1528. +
  1529. +on_input_dev_error:
  1530. +   imx_adc_put_iomem(ts->regs, ts->imx_adc);
  1531. +   imx_adc_unregister_ts(ts->imx_adc, ts);
  1532. +on_register_error:
  1533. +   kfree(ts);
  1534. +   return rc;
  1535. +}
  1536. +
  1537. +static void __devexit imx_ts_remove_input_dev(struct imx_ts_device *ts)
  1538. +{
  1539. +   input_unregister_device(ts->input);
  1540. +   input_free_device(ts->input);
  1541. +}
  1542. +
  1543. +static int __devexit imx_ts_remove(struct platform_device *pdev)
  1544. +{
  1545. +   struct imx_ts_device *ts = platform_get_drvdata(pdev);
  1546. +
  1547. +   cancel_work_sync(&ts->work);
  1548. +   /* disable all interrupts sources */
  1549. +   writel(0xffffffff, ts->regs + TCQMR);
  1550. +   writel(TCQCR_QSM_STOP | TCQCR_PD_MSK, ts->regs + TCQCR);
  1551. +
  1552. +   imx_ts_remove_input_dev(ts);
  1553. +   imx_adc_put_iomem(ts->regs, ts->imx_adc);
  1554. +   imx_adc_unregister_ts(ts->imx_adc, ts);
  1555. +   kfree(ts);
  1556. +   platform_set_drvdata(pdev, NULL);
  1557. +
  1558. +   return 0;
  1559. +}
  1560. +
  1561. +static int __maybe_unused imx_ts_suspend(struct device *dev)
  1562. +{
  1563. +   struct platform_device *pdev =
  1564. +           container_of(dev, struct platform_device, dev);
  1565. +   struct imx_ts_device *ts = platform_get_drvdata(pdev);
  1566. +
  1567. +   return 0;
  1568. +}
  1569. +
  1570. +static int __maybe_unused imx_ts_resume(struct device *dev)
  1571. +{
  1572. +   struct platform_device *pdev =
  1573. +           container_of(dev, struct platform_device, dev);
  1574. +   struct imx_ts_device *ts = platform_get_drvdata(pdev);
  1575. +
  1576. +   return 0;
  1577. +}
  1578. +
  1579. +static const struct dev_pm_ops ts_pm_ops = {
  1580. +#ifdef CONFIG_PM
  1581. +   .suspend = imx_ts_suspend,
  1582. +   .resume = imx_ts_resume,
  1583. +#endif
  1584. +};
  1585. +
  1586. +static struct platform_driver imx_ts_driver = {
  1587. +   .driver = {
  1588. +       .name = "mx25-ts",
  1589. +       .owner = THIS_MODULE,
  1590. +       .pm = &ts_pm_ops,
  1591. +   },
  1592. +   .probe = imx_ts_probe,
  1593. +   .remove = __devexit_p(imx_ts_remove),
  1594. +};
  1595. +
  1596. +static int __init imx_tsc_init(void)
  1597. +{
  1598. +   int ret;
  1599. +
  1600. +   ret = platform_driver_register(&imx_ts_driver);
  1601. +   if (ret)
  1602. +       pr_err("%s: failed to add ts driver\n", __func__);
  1603. +   return ret;
  1604. +}
  1605. +
  1606. +module_init(imx_tsc_init);
  1607. diff --git a/arch/arm/plat-mxc/include/mach/adc.h b/arch/arm/plat-mxc/include/mach/adc.h
  1608. new file mode 100644
  1609. index 0000000..42e4899
  1610. --- /dev/null
  1611. +++ b/arch/arm/plat-mxc/include/mach/adc.h
  1612. @@ -0,0 +1,47 @@
  1613. +/*
  1614. + * Copyright (C) 2011 Juergen Beisert, Pengutronix <kernel@pengutronix.de>
  1615. + *
  1616. + * This software is licensed under the terms of the GNU General Public
  1617. + * License version 2, as published by the Free Software Foundation, and
  1618. + * may be copied, distributed, and modified under those terms.
  1619. + *
  1620. + * This program is distributed in the hope that it will be useful,
  1621. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  1622. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  1623. + * GNU General Public License for more details.
  1624. + *
  1625. + */
  1626. +
  1627. +#ifndef __PLAT_MXC_MACH_ADC_H
  1628. +# define __PLAT_MXC_MACH_ADC_H
  1629. +
  1630. +#include <linux/irqreturn.h>
  1631. +
  1632. +/* List of shared registers */
  1633. +
  1634. +#define TGSR 4 /* read only */
  1635. +# define TGSR_TCQINT (1 << 0)
  1636. +# define TGSR_GCQINT (1 << 1)
  1637. +# define TGSR_SLPINT (1 << 2)
  1638. +
  1639. +#define TICR 8 /* FIXME only TS relevant? */
  1640. +
  1641. +/* List of shared register bits */
  1642. +# define TGCR_PDBEN (1 << 24)
  1643. +# define TGCR_PDEN (1 << 23)
  1644. +# define TGCR_PEN_DEBT_MASK (0x7f << 25)
  1645. +# define TGCR_SET_PEN_DEBT(x) ((x) << 25)
  1646. +# define TGCR_HSYNCEN (1 << 6)
  1647. +# define TGCR_HSYNCPOL (1 << 7)
  1648. +
  1649. +/* functions from the main module */
  1650. +extern void __iomem *imx_adc_get_iomem(void*);
  1651. +extern void imx_adc_put_iomem(void __iomem *, void*);
  1652. +extern void *imx_adc_register_ts(void*, irqreturn_t (*)(void*));
  1653. +extern int imx_adc_unregister_ts(void*, void*);
  1654. +extern void *imx_adc_register_hwmon(void*, irqreturn_t (*)(void*));
  1655. +extern int imx_adc_unregister_hwmon(void*, void*);
  1656. +extern void imx_adc_ts_set_tgcr(void*, u32);
  1657. +extern unsigned imx_adc_get_period(void*);
  1658. +
  1659. +#endif /* __PLAT_MXC_MACH_ADC_H */
  1660. diff --git a/arch/arm/plat-mxc/include/mach/devices-common.h b/arch/arm/plat-mxc/include/mach/devices-common.h
  1661. index def9ba5..112bdd2 100644
  1662. --- a/arch/arm/plat-mxc/include/mach/devices-common.h
  1663. +++ b/arch/arm/plat-mxc/include/mach/devices-common.h
  1664. @@ -108,6 +108,20 @@ struct platform_device *__init imx_add_imx_fb(
  1665.         const struct imx_imx_fb_data *data,
  1666.         const struct imx_fb_platform_data *pdata);
  1667.  
  1668. +struct imx_adc_platform_data;
  1669. +struct imx_ts_platform_data;
  1670. +struct imx_hwmon_platform_data;
  1671. +struct imx_imx_adc_data {
  1672. +   resource_size_t iobase;
  1673. +   resource_size_t iosize;
  1674. +   resource_size_t irq;
  1675. +};
  1676. +struct platform_device *__init imx_add_imx_adc(
  1677. +       const struct imx_imx_adc_data *data,
  1678. +       const struct imx_adc_platform_data *adc_pdata,
  1679. +       const struct imx_ts_platform_data *ts_pdata,
  1680. +       const struct imx_hwmon_platform_data *hwmon_pdata);
  1681. +
  1682.  #include <mach/i2c.h>
  1683.  struct imx_imx_i2c_data {
  1684.     int id;
  1685. diff --git a/arch/arm/plat-mxc/include/mach/imxfb.h b/arch/arm/plat-mxc/include/mach/imxfb.h
  1686. index 9de8f06..6ca4a8b 100644
  1687. --- a/arch/arm/plat-mxc/include/mach/imxfb.h
  1688. +++ b/arch/arm/plat-mxc/include/mach/imxfb.h
  1689. @@ -19,6 +19,7 @@
  1690.  #define PCR_BPIX_12    (4 << 25)
  1691.  #define PCR_BPIX_16    (5 << 25)
  1692.  #define PCR_BPIX_18    (6 << 25)
  1693. +#define PCR_BPIX_24    (7 << 25)
  1694.  #define PCR_PIXPOL (1 << 24)
  1695.  #define PCR_FLMPOL (1 << 23)
  1696.  #define PCR_LPPOL  (1 << 22)
  1697. @@ -55,6 +56,7 @@ struct imx_fb_videomode {
  1698.     struct fb_videomode mode;
  1699.     u32 pcr;
  1700.     unsigned char   bpp;
  1701. +   unsigned height, width;
  1702.  };
  1703.  
  1704.  struct imx_fb_platform_data {
  1705. diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx25.h b/arch/arm/plat-mxc/include/mach/iomux-mx25.h
  1706. index f0726d4..04f5788 100644
  1707. --- a/arch/arm/plat-mxc/include/mach/iomux-mx25.h
  1708. +++ b/arch/arm/plat-mxc/include/mach/iomux-mx25.h
  1709. @@ -151,20 +151,25 @@
  1710.  #define MX25_PAD_D13__GPIO_4_7     IOMUX_PAD(0x288, 0x090, 0x05, 0, 0, NO_PAD_CTRL)
  1711.  
  1712.  #define MX25_PAD_D12__D12      IOMUX_PAD(0x28c, 0x094, 0x00, 0, 0, NO_PAD_CTRL)
  1713. +#define MX25_PAD_D12__LD19     IOMUX_PAD(0x28c, 0x094, 0x01, 0, 0, NO_PAD_CTRL)
  1714.  #define MX25_PAD_D12__GPIO_4_8     IOMUX_PAD(0x28c, 0x094, 0x05, 0, 0, NO_PAD_CTRL)
  1715.  
  1716.  #define MX25_PAD_D11__D11      IOMUX_PAD(0x290, 0x098, 0x00, 0, 0, NO_PAD_CTRL)
  1717. +#define MX25_PAD_D11__LD20     IOMUX_PAD(0x290, 0x098, 0x01, 0, 0, NO_PAD_CTRL)
  1718.  #define MX25_PAD_D11__GPIO_4_9     IOMUX_PAD(0x290, 0x098, 0x05, 0, 0, NO_PAD_CTRL)
  1719.  
  1720.  #define MX25_PAD_D10__D10      IOMUX_PAD(0x294, 0x09c, 0x00, 0, 0, NO_PAD_CTRL)
  1721. +#define MX25_PAD_D10__LD21     IOMUX_PAD(0x294, 0x09c, 0x01, 0, 0, NO_PAD_CTRL)
  1722.  #define MX25_PAD_D10__GPIO_4_10        IOMUX_PAD(0x294, 0x09c, 0x05, 0, 0, NO_PAD_CTRL)
  1723.  #define MX25_PAD_D10__USBOTG_OC        IOMUX_PAD(0x294, 0x09c, 0x06, 0x57c, 0, PAD_CTL_PUS_100K_UP)
  1724.  
  1725.  #define MX25_PAD_D9__D9            IOMUX_PAD(0x298, 0x0a0, 0x00, 0, 0, NO_PAD_CTRL)
  1726. +#define MX25_PAD_D9__LD22      IOMUX_PAD(0x298, 0x0a0, 0x01, 0, 0, NO_PAD_CTRL)
  1727.  #define MX25_PAD_D9__GPIO_4_11     IOMUX_PAD(0x298, 0x0a0, 0x05, 0, 0, NO_PAD_CTRL)
  1728.  #define MX25_PAD_D9__USBH2_PWR     IOMUX_PAD(0x298, 0x0a0, 0x06, 0, 0, PAD_CTL_PKE)
  1729.  
  1730.  #define MX25_PAD_D8__D8            IOMUX_PAD(0x29c, 0x0a4, 0x00, 0, 0, NO_PAD_CTRL)
  1731. +#define MX25_PAD_D8__LD23      IOMUX_PAD(0x29c, 0x0a4, 0x01, 0, 0, NO_PAD_CTRL)
  1732.  #define MX25_PAD_D8__GPIO_4_12     IOMUX_PAD(0x29c, 0x0a4, 0x05, 0, 0, NO_PAD_CTRL)
  1733.  #define MX25_PAD_D8__USBH2_OC      IOMUX_PAD(0x29c, 0x0a4, 0x06, 0x580, 0, PAD_CTL_PUS_100K_UP)
  1734.  
  1735. @@ -468,14 +473,14 @@
  1736.  #define MX25_PAD_GPIO_C__CAN2_TX   IOMUX_PAD(0x3f8, 0x1fc, 0x16, 0, 0, PAD_CTL_PUS_22K_UP)
  1737.  
  1738.  #define MX25_PAD_GPIO_D__GPIO_D        IOMUX_PAD(0x3fc, 0x200, 0x10, 0, 0, NO_PAD_CTRL)
  1739. -#define MX25_PAD_GPIO_E__LD16      IOMUX_PAD(0x400, 0x204, 0x02, 0, 0, NO_PAD_CTRL)
  1740.  #define MX25_PAD_GPIO_D__CAN2_RX   IOMUX_PAD(0x3fc, 0x200, 0x16, 0x484, 1, PAD_CTL_PUS_22K_UP)
  1741.  
  1742.  #define MX25_PAD_GPIO_E__GPIO_E        IOMUX_PAD(0x400, 0x204, 0x10, 0, 0, NO_PAD_CTRL)
  1743. -#define MX25_PAD_GPIO_F__LD17      IOMUX_PAD(0x404, 0x208, 0x02, 0, 0, NO_PAD_CTRL)
  1744. +#define MX25_PAD_GPIO_E__LD16      IOMUX_PAD(0x400, 0x204, 0x02, 0, 0, NO_PAD_CTRL)
  1745.  #define MX25_PAD_GPIO_E__AUD7_TXD  IOMUX_PAD(0x400, 0x204, 0x14, 0, 0, NO_PAD_CTRL)
  1746.  
  1747.  #define MX25_PAD_GPIO_F__GPIO_F        IOMUX_PAD(0x404, 0x208, 0x10, 0, 0, NO_PAD_CTRL)
  1748. +#define MX25_PAD_GPIO_F__LD17      IOMUX_PAD(0x404, 0x208, 0x02, 0, 0, NO_PAD_CTRL)
  1749.  #define MX25_PAD_GPIO_F__AUD7_TXC  IOMUX_PAD(0x404, 0x208, 0x14, 0, 0, NO_PAD_CTRL)
  1750.  
  1751.  #define MX25_PAD_EXT_ARMCLK__EXT_ARMCLK    IOMUX_PAD(0x000, 0x20c, 0x10, 0, 0, NO_PAD_CTRL)
  1752. diff --git a/arch/arm/plat-mxc/include/mach/mx25.h b/arch/arm/plat-mxc/include/mach/mx25.h
  1753. index ccebf5b..d5f4ec8 100644
  1754. --- a/arch/arm/plat-mxc/include/mach/mx25.h
  1755. +++ b/arch/arm/plat-mxc/include/mach/mx25.h
  1756. @@ -40,6 +40,7 @@
  1757.  #define MX25_FEC_BASE_ADDR     0x50038000
  1758.  #define MX25_SSI2_BASE_ADDR        0x50014000
  1759.  #define MX25_SSI1_BASE_ADDR        0x50034000
  1760. +#define MX25_ADC_BASE_ADDR     0x50030000
  1761.  #define MX25_NFC_BASE_ADDR     0xbb000000
  1762.  #define MX25_IIM_BASE_ADDR     0x53ff0000
  1763.  #define MX25_DRYICE_BASE_ADDR      0x53ffc000
  1764. @@ -92,6 +93,7 @@
  1765.  #define MX25_INT_CAN1      43
  1766.  #define MX25_INT_CAN2      44
  1767.  #define MX25_INT_UART1     45
  1768. +#define MX25_INT_ADC       46
  1769.  #define MX25_INT_GPIO2     51
  1770.  #define MX25_INT_GPIO1     52
  1771.  #define MX25_INT_FEC       57
  1772. diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c
  1773. index 7496d04..5685de9 100644
  1774. --- a/drivers/video/backlight/pwm_bl.c
  1775. +++ b/drivers/video/backlight/pwm_bl.c
  1776. @@ -9,6 +9,7 @@
  1777.   * it under the terms of the GNU General Public License version 2 as
  1778.   * published by the Free Software Foundation.
  1779.   */
  1780. +#define DEBUG
  1781.  
  1782.  #include <linux/module.h>
  1783.  #include <linux/kernel.h>
  1784. @@ -45,12 +46,13 @@ static int pwm_backlight_update_status(struct backlight_device *bl)
  1785.     if (bl->props.fb_blank != FB_BLANK_UNBLANK)
  1786.         brightness = 0;
  1787.  
  1788. +   pr_debug("%s: backlight o%s\n", __func__, brightness != 0 ? "n" : "ff");
  1789. +
  1790.     if (pb->notify)
  1791.         brightness = pb->notify(pb->dev, brightness);
  1792.  
  1793.     if (brightness == 0) {
  1794.         pwm_config(pb->pwm, 0, pb->period);
  1795. -       pwm_disable(pb->pwm);
  1796.     } else {
  1797.         brightness = pb->lth_brightness +
  1798.             (brightness * (pb->period - pb->lth_brightness) / max);
  1799. @@ -89,6 +91,7 @@ static int pwm_backlight_probe(struct platform_device *pdev)
  1800.     struct platform_pwm_backlight_data *data = pdev->dev.platform_data;
  1801.     struct backlight_device *bl;
  1802.     struct pwm_bl_data *pb;
  1803. +   struct device *parent;
  1804.     int ret;
  1805.  
  1806.     if (!data) {
  1807. @@ -128,7 +131,8 @@ static int pwm_backlight_probe(struct platform_device *pdev)
  1808.     memset(&props, 0, sizeof(struct backlight_properties));
  1809.     props.type = BACKLIGHT_RAW;
  1810.     props.max_brightness = data->max_brightness;
  1811. -   bl = backlight_device_register(dev_name(&pdev->dev), &pdev->dev, pb,
  1812. +   parent = pdev->dev.parent ? pdev->dev.parent : &pdev->dev;
  1813. +   bl = backlight_device_register(dev_name(&pdev->dev), parent, pb,
  1814.                        &pwm_backlight_ops, &props);
  1815.     if (IS_ERR(bl)) {
  1816.         dev_err(&pdev->dev, "failed to register backlight\n");
  1817. @@ -137,7 +141,7 @@ static int pwm_backlight_probe(struct platform_device *pdev)
  1818.     }
  1819.  
  1820.     bl->props.brightness = data->dft_brightness;
  1821. -   backlight_update_status(bl);
  1822. +// backlight_update_status(bl);
  1823.  
  1824.     platform_set_drvdata(pdev, bl);
  1825.     return 0;
  1826. diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c
  1827. index f135dbe..2ca737f 100644
  1828. --- a/drivers/video/imxfb.c
  1829. +++ b/drivers/video/imxfb.c
  1830. @@ -31,6 +31,8 @@
  1831.  #include <linux/dma-mapping.h>
  1832.  #include <linux/io.h>
  1833.  #include <linux/math64.h>
  1834. +#include <linux/backlight.h>
  1835. +#include <linux/lcd.h>
  1836.  
  1837.  #include <mach/imxfb.h>
  1838.  #include <mach/hardware.h>
  1839. @@ -156,14 +158,20 @@ struct imxfb_info {
  1840.                 cmap_static:1,
  1841.                 unused:30;
  1842.  
  1843. +   unsigned        line_length;
  1844. +
  1845.     struct imx_fb_videomode *mode;
  1846.     int         num_modes;
  1847. +   void (*lcd_power)(int);
  1848. +   void (*backlight_power)(int);
  1849. +
  1850.  #ifdef PWMR_BACKLIGHT_AVAILABLE
  1851.     struct backlight_device *bl;
  1852.  #endif
  1853. -
  1854. -   void (*lcd_power)(int);
  1855. -   void (*backlight_power)(int);
  1856. +#ifdef CONFIG_LCD_CLASS_DEVICE
  1857. +   struct lcd_device   *lcd;
  1858. +   int         lcd_power_state;
  1859. +#endif
  1860.  };
  1861.  
  1862.  #define IMX_NAME   "IMX"
  1863. @@ -174,6 +182,14 @@ struct imxfb_info {
  1864.  #define MIN_XRES   64
  1865.  #define MIN_YRES   64
  1866.  
  1867. +/* memory to display mapping is 0123 -> 2301 */
  1868. +static struct imxfb_rgb def_rgb_24 = {
  1869. +   .blue = {.offset = 0, .length = 8,},
  1870. +   .transp = {.offset = 8, .length = 0,},
  1871. +   .red = {.offset = 16, .length = 8,},
  1872. +   .green = {.offset = 24, .length = 8,},
  1873. +};
  1874. +
  1875.  /* Actually this really is 18bit support, the lowest 2 bits of each colour
  1876.   * are unused in hardware. We claim to have 24bit support to make software
  1877.   * like X work, which does not support 18bit.
  1878. @@ -300,6 +316,47 @@ static const struct imx_fb_videomode *imxfb_find_mode(struct imxfb_info *fbi)
  1879.     return NULL;
  1880.  }
  1881.  
  1882. +static u32 imxfb_calc_dclk(struct imxfb_info *fbi, struct fb_var_screeninfo *var)
  1883. +{
  1884. +   unsigned input_clk = clk_get_rate(fbi->clk); /* in [Hz] */
  1885. +   unsigned dclk = PICOS2KHZ(var->pixclock) * 1000; /* from [psec] to [Hz] */
  1886. +   u32 pcr;
  1887. +
  1888. +   pr_debug("%s: calculating pixel clock from %u Hz main clock\n",
  1889. +           __func__, input_clk);
  1890. +   pr_debug("%s: target pixel clock should be %u Hz\n",
  1891. +           __func__, dclk);
  1892. +
  1893. +   pcr = DIV_ROUND_UP(input_clk, dclk);
  1894. +
  1895. +   if (pcr > 1)
  1896. +       pcr--;
  1897. +   else {
  1898. +       pr_debug("%s: must limit the pixel clock to %u Hz\n",
  1899. +               __func__, input_clk / 2);
  1900. +       pcr = 1;    /* '1' means '/2' */
  1901. +   }
  1902. +   /*
  1903. +    * TODO: output clock must be less than one third of HCLK for TFT mode
  1904. +    * and one fourth of HCLK for CSTN mode
  1905. +    */
  1906. +   pr_debug("%s: clock divider is now %u\n", __func__, pcr + 1);
  1907. +
  1908. +   if (pcr > 0x3F) {
  1909. +       pcr = 0x3F;
  1910. +       pr_warn("Must extend the pixel clock to %u Hz\n",
  1911. +               input_clk / (pcr + 1));
  1912. +   }
  1913. +
  1914. +   pr_debug("%s: resulting pixel clock frequency is: %u Hz\n",
  1915. +           __func__, input_clk / (pcr + 1));
  1916. +
  1917. +   /* the real pixel clock frequency for this mode */
  1918. +   var->pixclock = KHZ2PICOS((input_clk / (pcr + 1)) / 1000);
  1919. +
  1920. +   return pcr;
  1921. +}
  1922. +
  1923.  /*
  1924.   *  imxfb_check_var():
  1925.   *    Round up in the following order: bits_per_pixel, xres,
  1926. @@ -311,9 +368,7 @@ static int imxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
  1927.     struct imxfb_info *fbi = info->par;
  1928.     struct imxfb_rgb *rgb;
  1929.     const struct imx_fb_videomode *imxfb_mode;
  1930. -   unsigned long lcd_clk;
  1931. -   unsigned long long tmp;
  1932. -   u32 pcr = 0;
  1933. +   u32 pcr;
  1934.  
  1935.     if (var->xres < MIN_XRES)
  1936.         var->xres = MIN_XRES;
  1937. @@ -337,33 +392,30 @@ static int imxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
  1938.     var->sync       = imxfb_mode->mode.sync;
  1939.     var->xres_virtual   = max(var->xres_virtual, var->xres);
  1940.     var->yres_virtual   = max(var->yres_virtual, var->yres);
  1941. +   var->width      = imxfb_mode->width ? imxfb_mode->width : -1;
  1942. +   var->height     = imxfb_mode->height ? imxfb_mode->height : -1;
  1943.  
  1944.     pr_debug("var->bits_per_pixel=%d\n", var->bits_per_pixel);
  1945.  
  1946. -   lcd_clk = clk_get_rate(fbi->clk);
  1947. -
  1948. -   tmp = var->pixclock * (unsigned long long)lcd_clk;
  1949. -
  1950. -   do_div(tmp, 1000000);
  1951. -
  1952. -   if (do_div(tmp, 1000000) > 500000)
  1953. -       tmp++;
  1954. -
  1955. -   pcr = (unsigned int)tmp;
  1956. -
  1957. -   if (--pcr > 0x3F) {
  1958. -       pcr = 0x3F;
  1959. -       printk(KERN_WARNING "Must limit pixel clock to %luHz\n",
  1960. -               lcd_clk / pcr);
  1961. -   }
  1962. +   pcr = imxfb_calc_dclk(fbi, var);
  1963.  
  1964.     switch (var->bits_per_pixel) {
  1965.     case 32:
  1966. -       pcr |= PCR_BPIX_18;
  1967. +   case 24:
  1968. +       pr_debug("%s establishing a %u bpp mode\n", __func__, var->bits_per_pixel);
  1969. +       pcr |= PCR_BPIX_24 | PCR_END_BYTE_SWAP;
  1970.         rgb = &def_rgb_18;
  1971. +       var->bits_per_pixel = 32;
  1972. +       break;
  1973. +   case 18:
  1974. +       pr_debug("%s establishing a 18 bpp mode\n", __func__);
  1975. +       pcr |= PCR_BPIX_18 | PCR_END_SEL; /* Microsoft BGR */
  1976. +       rgb = &def_rgb_18;
  1977. +       var->bits_per_pixel = 32;
  1978.         break;
  1979. -   case 16:
  1980.     default:
  1981. +       var->bits_per_pixel = 16;
  1982. +   case 16:
  1983.         if (cpu_is_mx1())
  1984.             pcr |= PCR_BPIX_12;
  1985.         else
  1986. @@ -427,10 +479,9 @@ static int imxfb_set_par(struct fb_info *info)
  1987.         info->fix.visual = FB_VISUAL_STATIC_PSEUDOCOLOR;
  1988.     }
  1989.  
  1990. -   info->fix.line_length = var->xres_virtual * var->bits_per_pixel / 8;
  1991.     fbi->palette_size = var->bits_per_pixel == 8 ? 256 : 16;
  1992. -
  1993.     imxfb_activate_var(var, info);
  1994. +   info->fix.line_length = fbi->line_length;
  1995.  
  1996.     return 0;
  1997.  }
  1998. @@ -453,8 +504,17 @@ static int imxfb_bl_update_status(struct backlight_device *bl)
  1999.     if (bl->props.fb_blank != FB_BLANK_UNBLANK)
  2000.         brightness = 0;
  2001.  
  2002. +   pr_debug("%s called with '%d'\n", __func__, brightness);
  2003. +
  2004.     fbi->pwmr = (fbi->pwmr & ~0xFF) | brightness;
  2005.  
  2006. +   if (fbi->backlight_power) {
  2007. +       if (brightness)
  2008. +           fbi->backlight_power(true);
  2009. +       else
  2010. +           fbi->backlight_power(false);
  2011. +   }
  2012. +
  2013.     if (bl->props.fb_blank != FB_BLANK_UNBLANK)
  2014.         clk_enable(fbi->clk);
  2015.     writel(fbi->pwmr, fbi->regs + LCDC_PWMR);
  2016. @@ -503,10 +563,57 @@ static void imxfb_exit_backlight(struct imxfb_info *fbi)
  2017.  }
  2018.  #endif
  2019.  
  2020. -static void imxfb_enable_controller(struct imxfb_info *fbi)
  2021. +#ifdef CONFIG_LCD_CLASS_DEVICE
  2022. +
  2023. +static inline struct imxfb_info *to_our_lcd(struct lcd_device *lcd)
  2024. +{
  2025. +   return lcd_get_data(lcd);
  2026. +}
  2027. +
  2028. +static int imxfb_lcd_get_power(struct lcd_device *lcd)
  2029. +{
  2030. +   struct imxfb_info *fbi = to_our_lcd(lcd);
  2031. +
  2032. +   return fbi->lcd_power_state;
  2033. +}
  2034. +
  2035. +static int imxfb_lcd_set_power(struct lcd_device *lcd, int power)
  2036. +{
  2037. +   struct imxfb_info *fbi = to_our_lcd(lcd);
  2038. +   int lcd_power = 1;
  2039. +
  2040. +   if (power == FB_BLANK_POWERDOWN)
  2041. +       lcd_power = 0;
  2042. +
  2043. +   fbi->lcd_power(lcd_power);
  2044. +   fbi->lcd_power_state = power;
  2045. +
  2046. +   return 0;
  2047. +}
  2048. +
  2049. +static struct lcd_ops imxfb_lcd_ops = {
  2050. +   .get_power = imxfb_lcd_get_power,
  2051. +   .set_power = imxfb_lcd_set_power,
  2052. +};
  2053. +
  2054. +static void imxfb_init_lcd(struct imxfb_info *fbi)
  2055.  {
  2056. -   pr_debug("Enabling LCD controller\n");
  2057. +   if (fbi->lcd)
  2058. +       return;
  2059. +
  2060. +   fbi->lcd = lcd_device_register("imxfb-lcd", &fbi->pdev->dev, fbi,
  2061. +                   &imxfb_lcd_ops);
  2062. +}
  2063. +
  2064. +static void imxfb_exit_lcd(struct imxfb_info *fbi)
  2065. +{
  2066. +   if (fbi->lcd)
  2067. +       lcd_device_unregister(fbi->lcd);
  2068. +}
  2069. +#endif
  2070.  
  2071. +static void imxfb_enable_controller(struct imxfb_info *fbi)
  2072. +{
  2073.     writel(fbi->screen_dma, fbi->regs + LCDC_SSA);
  2074.  
  2075.     /* panning offset 0 (0 pixel offset)        */
  2076. @@ -523,22 +630,10 @@ static void imxfb_enable_controller(struct imxfb_info *fbi)
  2077.     writel(RMCR_LCDC_EN_MX1, fbi->regs + LCDC_RMCR);
  2078.  
  2079.     clk_enable(fbi->clk);
  2080. -
  2081. -   if (fbi->backlight_power)
  2082. -       fbi->backlight_power(1);
  2083. -   if (fbi->lcd_power)
  2084. -       fbi->lcd_power(1);
  2085.  }
  2086.  
  2087.  static void imxfb_disable_controller(struct imxfb_info *fbi)
  2088.  {
  2089. -   pr_debug("Disabling LCD controller\n");
  2090. -
  2091. -   if (fbi->backlight_power)
  2092. -       fbi->backlight_power(0);
  2093. -   if (fbi->lcd_power)
  2094. -       fbi->lcd_power(0);
  2095. -
  2096.     clk_disable(fbi->clk);
  2097.  
  2098.     writel(0, fbi->regs + LCDC_RMCR);
  2099. @@ -548,17 +643,17 @@ static int imxfb_blank(int blank, struct fb_info *info)
  2100.  {
  2101.     struct imxfb_info *fbi = info->par;
  2102.  
  2103. -   pr_debug("imxfb_blank: blank=%d\n", blank);
  2104. -
  2105.     switch (blank) {
  2106.     case FB_BLANK_POWERDOWN:
  2107.     case FB_BLANK_VSYNC_SUSPEND:
  2108.     case FB_BLANK_HSYNC_SUSPEND:
  2109.     case FB_BLANK_NORMAL:
  2110. +       pr_debug("%s: LCDC off\n", __func__);
  2111.         imxfb_disable_controller(fbi);
  2112.         break;
  2113.  
  2114.     case FB_BLANK_UNBLANK:
  2115. +       pr_debug("%s: LCDC on\n", __func__);
  2116.         imxfb_enable_controller(fbi);
  2117.         break;
  2118.     }
  2119. @@ -619,9 +714,10 @@ static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *inf
  2120.             info->fix.id, var->lower_margin);
  2121.  #endif
  2122.  
  2123. -   /* physical screen start address        */
  2124. -   writel(VPW_VPW(var->xres * var->bits_per_pixel / 8 / 4),
  2125. -       fbi->regs + LCDC_VPW);
  2126. +   /* physical line length in bytes */
  2127. +   fbi->line_length = var->xres * var->bits_per_pixel / 8;
  2128. +   /* and the controller wants this value in 32 bit words */
  2129. +   writel(VPW_VPW(fbi->line_length >> 2), fbi->regs + LCDC_VPW);
  2130.  
  2131.     writel(HCR_H_WIDTH(var->hsync_len - 1) |
  2132.         HCR_H_WAIT_1(var->right_margin - 1) |
  2133. @@ -682,8 +778,6 @@ static int __init imxfb_init_fbinfo(struct platform_device *pdev)
  2134.     struct imx_fb_platform_data *pdata = pdev->dev.platform_data;
  2135.     struct fb_info *info = dev_get_drvdata(&pdev->dev);
  2136.     struct imxfb_info *fbi = info->par;
  2137. -   struct imx_fb_videomode *m;
  2138. -   int i;
  2139.  
  2140.     pr_debug("%s\n",__func__);
  2141.  
  2142. @@ -704,8 +798,6 @@ static int __init imxfb_init_fbinfo(struct platform_device *pdev)
  2143.  
  2144.     info->var.nonstd        = 0;
  2145.     info->var.activate      = FB_ACTIVATE_NOW;
  2146. -   info->var.height        = -1;
  2147. -   info->var.width = -1;
  2148.     info->var.accel_flags       = 0;
  2149.     info->var.vmode         = FB_VMODE_NONINTERLACED;
  2150.  
  2151. @@ -721,13 +813,49 @@ static int __init imxfb_init_fbinfo(struct platform_device *pdev)
  2152.     fbi->lcd_power          = pdata->lcd_power;
  2153.     fbi->backlight_power        = pdata->backlight_power;
  2154.  
  2155. -   for (i = 0, m = &pdata->mode[0]; i < pdata->num_modes; i++, m++)
  2156. -       info->fix.smem_len = max_t(size_t, info->fix.smem_len,
  2157. -               m->mode.xres * m->mode.yres * m->bpp / 8);
  2158. -
  2159.     return 0;
  2160.  }
  2161.  
  2162. +/*
  2163. + * calculate the minimal required framebuffer size and honor
  2164. + * some physical contraints
  2165. + */
  2166. +static unsigned __init imxfb_calc_fbuffer_size(struct platform_device *pdev)
  2167. +{
  2168. +   struct imx_fb_platform_data *pdata = pdev->dev.platform_data;
  2169. +   struct imx_fb_videomode *m;
  2170. +   size_t max_size = 0;
  2171. +   int i;
  2172. +   unsigned bpp;
  2173. +
  2174. +   for (i = 0, m = &pdata->mode[0]; i < pdata->num_modes; i++, m++) {
  2175. +       switch (m->bpp) {
  2176. +       case 2:
  2177. +       case 4:
  2178. +       case 8:
  2179. +           bpp = 8;
  2180. +           break;
  2181. +       case 12:
  2182. +       case 15:
  2183. +       case 16:
  2184. +           bpp = 16;
  2185. +           break;
  2186. +       case 18:
  2187. +       case 24:
  2188. +       case 32:
  2189. +           bpp = 32;
  2190. +           break;
  2191. +       default:
  2192. +           dev_err(&pdev->dev,"%u is an unsupported bit per pixel value\n", m->bpp);
  2193. +           return 0;
  2194. +       }
  2195. +       max_size = max_t(size_t, max_size, m->mode.xres * m->mode.yres * bpp / 8);
  2196. +   }
  2197. +
  2198. +   dev_dbg(&pdev->dev,"need %u kiB of memory for the framebuffer\n", max_size);
  2199. +   return max_size;
  2200. +}
  2201. +
  2202.  static int __init imxfb_probe(struct platform_device *pdev)
  2203.  {
  2204.     struct imxfb_info *fbi;
  2205. @@ -784,6 +912,7 @@ static int __init imxfb_probe(struct platform_device *pdev)
  2206.     }
  2207.  
  2208.     if (!pdata->fixed_screen_cpu) {
  2209. +       info->fix.smem_len = imxfb_calc_fbuffer_size(pdev);
  2210.         fbi->map_size = PAGE_ALIGN(info->fix.smem_len);
  2211.         fbi->map_cpu = dma_alloc_writecombine(&pdev->dev,
  2212.                 fbi->map_size, &fbi->map_dma, GFP_KERNEL);
  2213. @@ -806,6 +935,8 @@ static int __init imxfb_probe(struct platform_device *pdev)
  2214.         fbi->screen_cpu = fbi->map_cpu;
  2215.         fbi->screen_dma = fbi->map_dma;
  2216.         info->fix.smem_start = fbi->screen_dma;
  2217. +       /* TODO this is a stupid solution! We need the available memory from the platform! */
  2218. +       info->fix.smem_len = imxfb_calc_fbuffer_size(pdev);
  2219.     }
  2220.  
  2221.     if (pdata->init) {
  2222. @@ -827,23 +958,36 @@ static int __init imxfb_probe(struct platform_device *pdev)
  2223.      */
  2224.     imxfb_check_var(&info->var, info);
  2225.  
  2226. -   ret = fb_alloc_cmap(&info->cmap, 1 << info->var.bits_per_pixel, 0);
  2227. -   if (ret < 0)
  2228. +   imxfb_set_par(info);
  2229. +
  2230. +   ret = fb_alloc_cmap(&info->cmap, fbi->palette_size, 0);
  2231. +   if (ret < 0) {
  2232. +       dev_err(&pdev->dev, "cannot allocate a cmap\n");
  2233.         goto failed_cmap;
  2234. +   }
  2235.  
  2236. -   imxfb_set_par(info);
  2237.     ret = register_framebuffer(info);
  2238.     if (ret < 0) {
  2239.         dev_err(&pdev->dev, "failed to register framebuffer\n");
  2240.         goto failed_register;
  2241.     }
  2242.  
  2243. -   imxfb_enable_controller(fbi);
  2244.     fbi->pdev = pdev;
  2245. +
  2246.  #ifdef PWMR_BACKLIGHT_AVAILABLE
  2247. -   imxfb_init_backlight(fbi);
  2248. +   if (fbi->backlight_power)
  2249. +       imxfb_init_backlight(fbi);
  2250.  #endif
  2251. -
  2252. +#ifdef CONFIG_LCD_CLASS_DEVICE
  2253. +   if (fbi->lcd_power)
  2254. +       imxfb_init_lcd(fbi);
  2255. +#endif
  2256. +   /*
  2257. +    * enable the whole chain of LCD, Backlight and LCD controller
  2258. +    * Note: the order the members of the chain are called depends on their
  2259. +    * registration!
  2260. +    */
  2261. +   fb_blank(info, 0);
  2262.     return 0;
  2263.  
  2264.  failed_register:
  2265. @@ -880,6 +1024,9 @@ static int __devexit imxfb_remove(struct platform_device *pdev)
  2266.  
  2267.     imxfb_disable_controller(fbi);
  2268.  
  2269. +#ifdef CONFIG_LCD_CLASS_DEVICE
  2270. +   imxfb_exit_lcd(fbi);
  2271. +#endif
  2272.  #ifdef PWMR_BACKLIGHT_AVAILABLE
  2273.     imxfb_exit_backlight(fbi);
  2274.  #endif
  2275. diff --git a/include/linux/platform_data/imx-adc.h b/include/linux/platform_data/imx-adc.h
  2276. new file mode 100644
  2277. index 0000000..63aabbf
  2278. --- /dev/null
  2279. +++ b/include/linux/platform_data/imx-adc.h
  2280. @@ -0,0 +1,54 @@
  2281. +/*
  2282. + * Copyright (C) 2011 Juergen Beisert, Pengutronix <kernel@pengutronix.de>
  2283. + *
  2284. + * This software is licensed under the terms of the GNU General Public
  2285. + * License version 2, as published by the Free Software Foundation, and
  2286. + * may be copied, distributed, and modified under those terms.
  2287. + *
  2288. + * This program is distributed in the hope that it will be useful,
  2289. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  2290. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  2291. + * GNU General Public License for more details.
  2292. + *
  2293. + */
  2294. +
  2295. +#ifndef __PLATFORM_DATA_IMX_ADC_H
  2296. +# define __PLATFORM_DATA_IMX_ADC_H
  2297. +
  2298. +/**
  2299. + * struct imx_adc_platform_data
  2300. + * @adc_freq; frequency in [Hz] the ADC should run (max 1.75 MHz)
  2301. + *
  2302. + * Describes the physical requirements to run the ADC unit.
  2303. + */
  2304. +struct imx_adc_platform_data {
  2305. +   unsigned long adc_freq;
  2306. +};
  2307. +
  2308. +/**
  2309. + * struct imx_ts_platform_data
  2310. + * @pen_debounce: time [ns] the pen signal needs to settle (touchscreen dependent)
  2311. + * @pen_treshold: minimum ADC value to detect a pressure as valid
  2312. + * @repeat_wait: time [ns] to wait between a repeated conversion
  2313. + * @settling_time: time [ns] the electrical signals must settle prior measurement
  2314. + * @sample_cnt: sample count per direction per measurement
  2315. + * @in_sync: 0: disabled, 1 in sync with a high active HSYNC, -1 low active HSYNC
  2316. + *
  2317. + * Describes the physical requirements for a specific touchscreen.
  2318. + */
  2319. +struct imx_ts_platform_data {
  2320. +   unsigned pen_debounce;
  2321. +   unsigned pen_treshold;
  2322. +   unsigned repeat_wait;
  2323. +   unsigned settling_time;
  2324. +   unsigned sample_cnt;
  2325. +   int in_sync;
  2326. +# define MEAS_IF_LOW_HSYNC -1
  2327. +# define MEAS_IF_HIG_HSYNC 1
  2328. +};
  2329. +
  2330. +struct imx_hwmon_platform_data {
  2331. +   unsigned dummy;
  2332. +};
  2333. +
  2334. +#endif /* __ASM_ARCH_MSM_SERIAL_HS_H */
  2335. --
  2336. 1.7.4.1
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement