Advertisement
Guest User

Untitled

a guest
May 31st, 2017
611
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Diff 91.59 KB | None | 0 0
  1. diff --git a/arch/arm/mach-msm/board-trout.h b/arch/arm/mach-msm/board-trout.h
  2. index 4f345a5..d1debc2 100644
  3. --- a/arch/arm/mach-msm/board-trout.h
  4. +++ b/arch/arm/mach-msm/board-trout.h
  5. @@ -1,5 +1,161 @@
  6. +/* linux/arch/arm/mach-msm/board-trout.h
  7. +** Author: Brian Swetland <swetland@google.com>
  8. +*/
  9. +#ifndef __ARCH_ARM_MACH_MSM_BOARD_TROUT_H
  10. +#define __ARCH_ARM_MACH_MSM_BOARD_TROUT_H
  11. +
  12. +#include <mach/board.h>
  13. +
  14. +#define MSM_SMI_BASE       0x00000000
  15. +#define MSM_SMI_SIZE       0x00800000
  16. +
  17. +#define MSM_EBI_BASE       0x10000000
  18. +#define MSM_EBI_SIZE       0x06e00000
  19. +
  20. +#define MSM_PMEM_GPU0_BASE 0x00000000
  21. +#define MSM_PMEM_GPU0_SIZE 0x00700000
  22. +
  23. +#define MSM_PMEM_MDP_BASE  0x02000000
  24. +#define MSM_PMEM_MDP_SIZE  0x00800000
  25. +
  26. +#define MSM_PMEM_ADSP_BASE      0x02800000
  27. +#define MSM_PMEM_ADSP_SIZE 0x00800000
  28. +
  29. +#define MSM_PMEM_CAMERA_BASE   0x03000000
  30. +#define MSM_PMEM_CAMERA_SIZE   0x00800000
  31. +
  32. +#define MSM_FB_BASE        0x03800000
  33. +#define MSM_FB_SIZE        0x00100000
  34. +
  35. +#define MSM_LINUX_BASE     MSM_EBI_BASE
  36. +#define MSM_LINUX_SIZE     0x06500000
  37. +
  38. +#define MSM_PMEM_GPU1_SIZE 0x800000
  39. +#define MSM_PMEM_GPU1_BASE MSM_RAM_CONSOLE_BASE - MSM_PMEM_GPU1_SIZE
  40. +
  41. +#define MSM_RAM_CONSOLE_BASE   MSM_EBI_BASE + 0x6d00000
  42. +#define MSM_RAM_CONSOLE_SIZE   128 * SZ_1K
  43. +
  44. +#if (MSM_FB_BASE + MSM_FB_SIZE) >= (MSM_PMEM_GPU1_BASE)
  45. +#error invalid memory map
  46. +#endif
  47. +
  48. +#define DECLARE_MSM_IOMAP
  49. +#include <mach/msm_iomap.h>
  50. +
  51. +#define TROUT_4_BALL_UP_0     1
  52. +#define TROUT_4_BALL_LEFT_0   18
  53. +#define TROUT_4_BALL_DOWN_0   57
  54. +#define TROUT_4_BALL_RIGHT_0  91
  55. +
  56. +#define TROUT_5_BALL_UP_0     94
  57. +#define TROUT_5_BALL_LEFT_0   18
  58. +#define TROUT_5_BALL_DOWN_0   90
  59. +#define TROUT_5_BALL_RIGHT_0  19
  60. +
  61. +#define TROUT_POWER_KEY     20
  62. +
  63. +#define TROUT_4_TP_LS_EN    19
  64. +#define TROUT_5_TP_LS_EN    1
  65.  
  66.  #define TROUT_CPLD_BASE   0xE8100000
  67.  #define TROUT_CPLD_START  0x98000000
  68.  #define TROUT_CPLD_SIZE   SZ_4K
  69.  
  70. +#define TROUT_GPIO_CABLE_IN1       (83)
  71. +#define TROUT_GPIO_CABLE_IN2       (49)
  72. +
  73. +#define TROUT_GPIO_START (128)
  74. +
  75. +#define TROUT_GPIO_INT_MASK0_REG            (0x0c)
  76. +#define TROUT_GPIO_INT_STAT0_REG            (0x0e)
  77. +#define TROUT_GPIO_INT_MASK1_REG            (0x14)
  78. +#define TROUT_GPIO_INT_STAT1_REG            (0x10)
  79. +
  80. +#define TROUT_GPIO_HAPTIC_PWM               (28)
  81. +#define TROUT_GPIO_PS_HOLD                  (25)
  82. +
  83. +#define TROUT_GPIO_MISC2_BASE               (TROUT_GPIO_START + 0x00)
  84. +#define TROUT_GPIO_MISC3_BASE               (TROUT_GPIO_START + 0x08)
  85. +#define TROUT_GPIO_MISC4_BASE               (TROUT_GPIO_START + 0x10)
  86. +#define TROUT_GPIO_MISC5_BASE               (TROUT_GPIO_START + 0x18)
  87. +#define TROUT_GPIO_INT2_BASE                (TROUT_GPIO_START + 0x20)
  88. +#define TROUT_GPIO_MISC1_BASE               (TROUT_GPIO_START + 0x28)
  89. +#define TROUT_GPIO_VIRTUAL_BASE             (TROUT_GPIO_START + 0x30)
  90. +#define TROUT_GPIO_INT5_BASE                (TROUT_GPIO_START + 0x48)
  91. +
  92. +#define TROUT_GPIO_CHARGER_EN               (TROUT_GPIO_MISC2_BASE + 0)
  93. +#define TROUT_GPIO_ISET                     (TROUT_GPIO_MISC2_BASE + 1)
  94. +#define TROUT_GPIO_H2W_DAT_DIR              (TROUT_GPIO_MISC2_BASE + 2)
  95. +#define TROUT_GPIO_H2W_CLK_DIR              (TROUT_GPIO_MISC2_BASE + 3)
  96. +#define TROUT_GPIO_H2W_DAT_GPO              (TROUT_GPIO_MISC2_BASE + 4)
  97. +#define TROUT_GPIO_H2W_CLK_GPO              (TROUT_GPIO_MISC2_BASE + 5)
  98. +#define TROUT_GPIO_H2W_SEL0                 (TROUT_GPIO_MISC2_BASE + 6)
  99. +#define TROUT_GPIO_H2W_SEL1                 (TROUT_GPIO_MISC2_BASE + 7)
  100. +
  101. +#define TROUT_GPIO_FLASH_EN                 (TROUT_GPIO_MISC3_BASE + 1)
  102. +#define TROUT_GPIO_I2C_PULL                 (TROUT_GPIO_MISC3_BASE + 2)
  103. +#define TROUT_GPIO_TP_I2C_PULL              (TROUT_GPIO_MISC3_BASE + 3)
  104. +#define TROUT_GPIO_TP_EN                    (TROUT_GPIO_MISC3_BASE + 4)
  105. +#define TROUT_GPIO_JOG_EN                   (TROUT_GPIO_MISC3_BASE + 5)
  106. +#define TROUT_GPIO_UI_LED_EN                (TROUT_GPIO_MISC3_BASE + 6)
  107. +#define TROUT_GPIO_QTKEY_LED_EN             (TROUT_GPIO_MISC3_BASE + 7)
  108. +
  109. +#define TROUT_GPIO_VCM_PWDN                 (TROUT_GPIO_MISC4_BASE + 0)
  110. +#define TROUT_GPIO_USB_H2W_SW               (TROUT_GPIO_MISC4_BASE + 1)
  111. +#define TROUT_GPIO_COMPASS_RST_N            (TROUT_GPIO_MISC4_BASE + 2)
  112. +#define TROUT_GPIO_HAPTIC_EN_UP             (TROUT_GPIO_MISC4_BASE + 3)
  113. +#define TROUT_GPIO_HAPTIC_EN_MAIN           (TROUT_GPIO_MISC4_BASE + 4)
  114. +#define TROUT_GPIO_USB_PHY_RST_N            (TROUT_GPIO_MISC4_BASE + 5)
  115. +#define TROUT_GPIO_WIFI_PA_RESETX           (TROUT_GPIO_MISC4_BASE + 6)
  116. +#define TROUT_GPIO_WIFI_EN                  (TROUT_GPIO_MISC4_BASE + 7)
  117. +
  118. +#define TROUT_GPIO_BT_32K_EN                (TROUT_GPIO_MISC5_BASE + 0)
  119. +#define TROUT_GPIO_MAC_32K_EN               (TROUT_GPIO_MISC5_BASE + 1)
  120. +#define TROUT_GPIO_MDDI_32K_EN              (TROUT_GPIO_MISC5_BASE + 2)
  121. +#define TROUT_GPIO_COMPASS_32K_EN           (TROUT_GPIO_MISC5_BASE + 3)
  122. +
  123. +#define TROUT_GPIO_NAVI_ACT_N               (TROUT_GPIO_INT2_BASE + 0)
  124. +#define TROUT_GPIO_COMPASS_IRQ              (TROUT_GPIO_INT2_BASE + 1)
  125. +#define TROUT_GPIO_SLIDING_DET              (TROUT_GPIO_INT2_BASE + 2)
  126. +#define TROUT_GPIO_AUD_HSMIC_DET_N          (TROUT_GPIO_INT2_BASE + 3)
  127. +#define TROUT_GPIO_SD_DOOR_N                (TROUT_GPIO_INT2_BASE + 4)
  128. +#define TROUT_GPIO_CAM_BTN_STEP1_N          (TROUT_GPIO_INT2_BASE + 5)
  129. +#define TROUT_GPIO_CAM_BTN_STEP2_N          (TROUT_GPIO_INT2_BASE + 6)
  130. +#define TROUT_GPIO_TP_ATT_N                 (TROUT_GPIO_INT2_BASE + 7)
  131. +#define TROUT_GPIO_BANK0_FIRST_INT_SOURCE   (TROUT_GPIO_NAVI_ACT_N)
  132. +#define TROUT_GPIO_BANK0_LAST_INT_SOURCE    (TROUT_GPIO_TP_ATT_N)
  133. +
  134. +#define TROUT_GPIO_H2W_DAT_GPI              (TROUT_GPIO_MISC1_BASE + 0)
  135. +#define TROUT_GPIO_H2W_CLK_GPI              (TROUT_GPIO_MISC1_BASE + 1)
  136. +#define TROUT_GPIO_CPLD128_VER_0            (TROUT_GPIO_MISC1_BASE + 4)
  137. +#define TROUT_GPIO_CPLD128_VER_1            (TROUT_GPIO_MISC1_BASE + 5)
  138. +#define TROUT_GPIO_CPLD128_VER_2            (TROUT_GPIO_MISC1_BASE + 6)
  139. +#define TROUT_GPIO_CPLD128_VER_3            (TROUT_GPIO_MISC1_BASE + 7)
  140. +
  141. +#define TROUT_GPIO_SDMC_CD_N                (TROUT_GPIO_VIRTUAL_BASE + 0)
  142. +#define TROUT_GPIO_END                      (TROUT_GPIO_SDMC_CD_N)
  143. +#define TROUT_GPIO_BANK1_FIRST_INT_SOURCE   (TROUT_GPIO_SDMC_CD_N)
  144. +#define TROUT_GPIO_BANK1_LAST_INT_SOURCE    (TROUT_GPIO_SDMC_CD_N)
  145. +
  146. +#define TROUT_GPIO_VIRTUAL_TO_REAL_OFFSET \
  147. +   (TROUT_GPIO_INT5_BASE - TROUT_GPIO_VIRTUAL_BASE)
  148. +
  149. +#define TROUT_INT_START (NR_MSM_IRQS + NR_GPIO_IRQS)
  150. +#define TROUT_INT_BANK0_COUNT (8)
  151. +#define TROUT_INT_BANK1_START (TROUT_INT_START + TROUT_INT_BANK0_COUNT)
  152. +#define TROUT_INT_BANK1_COUNT (1)
  153. +#define TROUT_INT_END (TROUT_INT_START + TROUT_INT_BANK0_COUNT + \
  154. +           TROUT_INT_BANK1_COUNT - 1)
  155. +#define TROUT_GPIO_TO_INT(n) (((n) <= TROUT_GPIO_BANK0_LAST_INT_SOURCE) ? \
  156. +   (TROUT_INT_START - TROUT_GPIO_BANK0_FIRST_INT_SOURCE + (n)) : \
  157. +   (TROUT_INT_BANK1_START - TROUT_GPIO_BANK1_FIRST_INT_SOURCE + (n)))
  158. +
  159. +#define TROUT_INT_TO_BANK(n) ((n - TROUT_INT_START) / TROUT_INT_BANK0_COUNT)
  160. +#define TROUT_INT_TO_MASK(n) (1U << ((n - TROUT_INT_START) & 7))
  161. +#define TROUT_BANK_TO_MASK_REG(bank) \
  162. +   (bank ? TROUT_GPIO_INT_MASK1_REG : TROUT_GPIO_INT_MASK0_REG)
  163. +#define TROUT_BANK_TO_STAT_REG(bank) \
  164. +   (bank ? TROUT_GPIO_INT_STAT1_REG : TROUT_GPIO_INT_STAT0_REG)
  165. +
  166. +#endif /* GUARD */
  167. diff --git a/arch/arm/mach-msm/devices-msm7x00.c b/arch/arm/mach-msm/devices-msm7x00.c
  168. index fde9d8f..e9991f3 100644
  169. --- a/arch/arm/mach-msm/devices-msm7x00.c
  170. +++ b/arch/arm/mach-msm/devices-msm7x00.c
  171. @@ -322,6 +322,74 @@ static struct platform_device *msm_sdcc_devices[] __initdata = {
  172.     &msm_device_sdc4,
  173.  };
  174.  
  175. +static struct resource resources_mddi0[] = {
  176. +   {
  177. +       .start  = MSM_PMDH_PHYS,
  178. +       .end    = MSM_PMDH_PHYS + MSM_PMDH_SIZE - 1,
  179. +       .flags  = IORESOURCE_MEM,
  180. +   },
  181. +   {
  182. +       .start  = INT_MDDI_PRI,
  183. +       .end    = INT_MDDI_PRI,
  184. +       .flags  = IORESOURCE_IRQ,
  185. +   },
  186. +};
  187. +
  188. +static struct resource resources_mddi1[] = {
  189. +   {
  190. +       .start  = MSM_EMDH_PHYS,
  191. +       .end    = MSM_EMDH_PHYS + MSM_EMDH_SIZE - 1,
  192. +       .flags  = IORESOURCE_MEM,
  193. +   },
  194. +   {
  195. +       .start  = INT_MDDI_EXT,
  196. +       .end    = INT_MDDI_EXT,
  197. +       .flags  = IORESOURCE_IRQ,
  198. +   },
  199. +};
  200. +
  201. +struct platform_device msm_device_mddi0 = {
  202. +   .name = "msm_mddi",
  203. +   .id = 0,
  204. +   .num_resources = ARRAY_SIZE(resources_mddi0),
  205. +   .resource = resources_mddi0,
  206. +   .dev = {
  207. +       .coherent_dma_mask      = 0xffffffff,
  208. +   },
  209. +};
  210. +
  211. +struct platform_device msm_device_mddi1 = {
  212. +   .name = "msm_mddi",
  213. +   .id = 1,
  214. +   .num_resources = ARRAY_SIZE(resources_mddi1),
  215. +   .resource = resources_mddi1,
  216. +   .dev = {
  217. +       .coherent_dma_mask      = 0xffffffff,
  218. +   },
  219. +};
  220. +
  221. +
  222. +static struct resource resources_mdp[] = {
  223. +   {
  224. +       .start  = MSM_MDP_PHYS,
  225. +       .end    = MSM_MDP_PHYS + MSM_MDP_SIZE - 1,
  226. +       .name   = "mdp",
  227. +       .flags  = IORESOURCE_MEM
  228. +   },
  229. +   {
  230. +       .start  = INT_MDP,
  231. +       .end    = INT_MDP,
  232. +       .flags  = IORESOURCE_IRQ,
  233. +   },
  234. +};
  235. +
  236. +struct platform_device msm_device_mdp = {
  237. +   .name = "msm_mdp",
  238. +   .id = 0,
  239. +   .num_resources = ARRAY_SIZE(resources_mdp),
  240. +   .resource = resources_mdp,
  241. +};
  242. +
  243.  int __init msm_add_sdcc(unsigned int controller, struct mmc_platform_data *plat,
  244.             unsigned int stat_irq, unsigned long stat_irq_flags)
  245.  {
  246. diff --git a/arch/arm/mach-msm/devices.h b/arch/arm/mach-msm/devices.h
  247. index 568443e..b238197 100644
  248. --- a/arch/arm/mach-msm/devices.h
  249. +++ b/arch/arm/mach-msm/devices.h
  250. @@ -34,6 +34,9 @@ extern struct platform_device msm_device_i2c;
  251.  extern struct platform_device msm_device_smd;
  252.  
  253.  extern struct platform_device msm_device_nand;
  254. +extern struct platform_device msm_device_mddi0;
  255. +extern struct platform_device msm_device_mddi1;
  256. +extern struct platform_device msm_device_mdp;
  257.  
  258.  extern struct clk msm_clocks_7x01a[];
  259.  extern unsigned msm_num_clocks_7x01a;
  260. diff --git a/arch/arm/mach-msm/include/mach/earlysuspend.h b/arch/arm/mach-msm/include/mach/earlysuspend.h
  261. new file mode 100755
  262. index 0000000..8343b81
  263. --- /dev/null
  264. +++ b/arch/arm/mach-msm/include/mach/earlysuspend.h
  265. @@ -0,0 +1,56 @@
  266. +/* include/linux/earlysuspend.h
  267. + *
  268. + * Copyright (C) 2007-2008 Google, Inc.
  269. + *
  270. + * This software is licensed under the terms of the GNU General Public
  271. + * License version 2, as published by the Free Software Foundation, and
  272. + * may be copied, distributed, and modified under those terms.
  273. + *
  274. + * This program is distributed in the hope that it will be useful,
  275. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  276. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  277. + * GNU General Public License for more details.
  278. + *
  279. + */
  280. +
  281. +#ifndef _LINUX_EARLYSUSPEND_H
  282. +#define _LINUX_EARLYSUSPEND_H
  283. +
  284. +#ifdef CONFIG_HAS_EARLYSUSPEND
  285. +#include <linux/list.h>
  286. +#endif
  287. +
  288. +/* The early_suspend structure defines suspend and resume hooks to be called
  289. + * when the user visible sleep state of the system changes, and a level to
  290. + * control the order. They can be used to turn off the screen and input
  291. + * devices that are not used for wakeup.
  292. + * Suspend handlers are called in low to high level order, resume handlers are
  293. + * called in the opposite order. If, when calling register_early_suspend,
  294. + * the suspend handlers have already been called without a matching call to the
  295. + * resume handlers, the suspend handler will be called directly from
  296. + * register_early_suspend. This direct call can violate the normal level order.
  297. + */
  298. +enum {
  299. +   EARLY_SUSPEND_LEVEL_BLANK_SCREEN = 50,
  300. +   EARLY_SUSPEND_LEVEL_STOP_DRAWING = 100,
  301. +   EARLY_SUSPEND_LEVEL_DISABLE_FB = 150,
  302. +};
  303. +struct early_suspend {
  304. +#ifdef CONFIG_HAS_EARLYSUSPEND
  305. +   struct list_head link;
  306. +   int level;
  307. +   void (*suspend)(struct early_suspend *h);
  308. +   void (*resume)(struct early_suspend *h);
  309. +#endif
  310. +};
  311. +
  312. +#ifdef CONFIG_HAS_EARLYSUSPEND
  313. +void register_early_suspend(struct early_suspend *handler);
  314. +void unregister_early_suspend(struct early_suspend *handler);
  315. +#else
  316. +#define register_early_suspend(handler) do { } while (0)
  317. +#define unregister_early_suspend(handler) do { } while (0)
  318. +#endif
  319. +
  320. +#endif
  321. +
  322. diff --git a/arch/arm/mach-msm/include/mach/htc_pwrsink.h b/arch/arm/mach-msm/include/mach/htc_pwrsink.h
  323. new file mode 100644
  324. index 0000000..0c3b70a
  325. --- /dev/null
  326. +++ b/arch/arm/mach-msm/include/mach/htc_pwrsink.h
  327. @@ -0,0 +1,87 @@
  328. +/* include/asm/mach-msm/htc_pwrsink.h
  329. + *
  330. + * Copyright (C) 2007 Google, Inc.
  331. + * Copyright (C) 2008 HTC Corporation.
  332. + *
  333. + * This software is licensed under the terms of the GNU General Public
  334. + * License version 2, as published by the Free Software Foundation, and
  335. + * may be copied, distributed, and modified under those terms.
  336. + *
  337. + * This program is distributed in the hope that it will be useful,
  338. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  339. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  340. + * GNU General Public License for more details.
  341. + *
  342. + */
  343. +#ifndef _ARCH_ARM_MACH_MSM_HTC_PWRSINK_H_
  344. +#define _ARCH_ARM_MACH_MSM_HTC_PWRSINK_H_
  345. +
  346. +#include <linux/platform_device.h>
  347. +#include <mach/earlysuspend.h>
  348. +
  349. +typedef enum {
  350. +   PWRSINK_AUDIO_PCM = 0,
  351. +   PWRSINK_AUDIO_MP3,
  352. +   PWRSINK_AUDIO_AAC,
  353. +
  354. +   PWRSINK_AUDIO_LAST = PWRSINK_AUDIO_AAC,
  355. +   PWRSINK_AUDIO_INVALID
  356. +} pwrsink_audio_id_type;
  357. +
  358. +struct pwr_sink_audio {
  359. +   unsigned volume;
  360. +   unsigned percent;
  361. +};
  362. +
  363. +typedef enum {
  364. +   PWRSINK_SYSTEM_LOAD = 0,
  365. +   PWRSINK_AUDIO,
  366. +   PWRSINK_BACKLIGHT,
  367. +   PWRSINK_LED_BUTTON,
  368. +   PWRSINK_LED_KEYBOARD,
  369. +   PWRSINK_GP_CLK,
  370. +   PWRSINK_BLUETOOTH,
  371. +   PWRSINK_CAMERA,
  372. +   PWRSINK_SDCARD,
  373. +   PWRSINK_VIDEO,
  374. +   PWRSINK_WIFI,
  375. +
  376. +   PWRSINK_LAST = PWRSINK_WIFI,
  377. +   PWRSINK_INVALID
  378. +} pwrsink_id_type;
  379. +
  380. +struct pwr_sink {
  381. +   pwrsink_id_type id;
  382. +   unsigned    ua_max;
  383. +   unsigned    percent_util;
  384. +};
  385. +
  386. +struct pwr_sink_platform_data {
  387. +   unsigned    num_sinks;
  388. +   struct pwr_sink *sinks;
  389. +   int (*suspend_late)(struct platform_device *, pm_message_t state);
  390. +   int (*resume_early)(struct platform_device *);
  391. +   void (*suspend_early)(struct early_suspend *);
  392. +   void (*resume_late)(struct early_suspend *);
  393. +};
  394. +
  395. +#ifndef CONFIG_HTC_PWRSINK
  396. +static inline int htc_pwrsink_set(pwrsink_id_type id, unsigned percent)
  397. +{
  398. +   return 0;
  399. +}
  400. +static inline int htc_pwrsink_audio_set(pwrsink_audio_id_type id,
  401. +   unsigned percent_utilized) { return 0; }
  402. +static inline int htc_pwrsink_audio_volume_set(
  403. +   pwrsink_audio_id_type id, unsigned volume) { return 0; }
  404. +static inline int htc_pwrsink_audio_path_set(unsigned path) { return 0; }
  405. +#else
  406. +extern int htc_pwrsink_set(pwrsink_id_type id, unsigned percent);
  407. +extern int htc_pwrsink_audio_set(pwrsink_audio_id_type id,
  408. +   unsigned percent_utilized);
  409. +extern int htc_pwrsink_audio_volume_set(pwrsink_audio_id_type id,
  410. +   unsigned volume);
  411. +extern int htc_pwrsink_audio_path_set(unsigned path);
  412. +#endif
  413. +
  414. +#endif
  415. diff --git a/arch/arm/mach-msm/include/mach/msm_hsusb.h b/arch/arm/mach-msm/include/mach/msm_hsusb.h
  416. new file mode 100644
  417. index 0000000..2d49b0f
  418. --- /dev/null
  419. +++ b/arch/arm/mach-msm/include/mach/msm_hsusb.h
  420. @@ -0,0 +1,74 @@
  421. +/* linux/include/asm-arm/arch-msm/hsusb.h
  422. + *
  423. + * Copyright (C) 2008 Google, Inc.
  424. + * Author: Brian Swetland <swetland@google.com>
  425. + *
  426. + * This software is licensed under the terms of the GNU General Public
  427. + * License version 2, as published by the Free Software Foundation, and
  428. + * may be copied, distributed, and modified under those terms.
  429. + *
  430. + * This program is distributed in the hope that it will be useful,
  431. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  432. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  433. + * GNU General Public License for more details.
  434. + *
  435. + */
  436. +
  437. +#ifndef __ASM_ARCH_MSM_HSUSB_H
  438. +#define __ASM_ARCH_MSM_HSUSB_H
  439. +
  440. +#include <linux/types.h>
  441. +
  442. +/* platform device data for msm_hsusb driver */
  443. +
  444. +#ifdef CONFIG_USB_FUNCTION
  445. +/* matches a product ID to a list of enabled functions */
  446. +struct msm_hsusb_product {
  447. +   /* product ID for usb_device_descriptor.idProduct */
  448. +   __u16 product_id;
  449. +
  450. +   /* bit mask of enabled usb_functions, matching ordering
  451. +   ** in msm_hsusb_platform_data.functions
  452. +   */
  453. +   __u32 functions;
  454. +};
  455. +#endif
  456. +
  457. +struct msm_hsusb_platform_data {
  458. +   /* hard reset the ULPI PHY */
  459. +   void (*phy_reset)(void);
  460. +
  461. +   /* for notification when USB is connected or disconnected */
  462. +   void (*usb_connected)(int);
  463. +
  464. +   /* val, reg pairs terminated by -1 */
  465. +   int *phy_init_seq;
  466. +
  467. +#ifdef CONFIG_USB_FUNCTION
  468. +   /* USB device descriptor fields */
  469. +   __u16 vendor_id;
  470. +
  471. +   /* Default product ID.
  472. +   ** This can be overridden dynamically based on the disabled
  473. +   ** state of the functions using the product_table.
  474. +   */
  475. +   __u16 product_id;
  476. +
  477. +   __u16 version;
  478. +   char *serial_number;
  479. +   char *product_name;
  480. +   char *manufacturer_name;
  481. +
  482. +   /* list of function drivers to bind to this configuration */
  483. +   int num_functions;
  484. +   char **functions;
  485. +
  486. +   /* if num_products is zero, then the default value in product_id
  487. +   ** is used for the configuration descriptor.
  488. +   */
  489. +   int num_products;
  490. +   struct msm_hsusb_product *products;
  491. +#endif
  492. +};
  493. +
  494. +#endif
  495. diff --git a/arch/arm/mach-msm/include/mach/msm_hsusb_hw.h b/arch/arm/mach-msm/include/mach/msm_hsusb_hw.h
  496. new file mode 100644
  497. index 0000000..8042b31
  498. --- /dev/null
  499. +++ b/arch/arm/mach-msm/include/mach/msm_hsusb_hw.h
  500. @@ -0,0 +1,204 @@
  501. +/*
  502. + * Copyright (C) 2007 Google, Inc.
  503. + * Author: Brian Swetland <swetland@google.com>
  504. + *
  505. + * This software is licensed under the terms of the GNU General Public
  506. + * License version 2, as published by the Free Software Foundation, and
  507. + * may be copied, distributed, and modified under those terms.
  508. + *
  509. + * This program is distributed in the hope that it will be useful,
  510. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  511. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  512. + * GNU General Public License for more details.
  513. + *
  514. + */
  515. +
  516. +#ifndef __LINUX_USB_GADGET_MSM72K_UDC_H__
  517. +#define __LINUX_USB_GADGET_MSM72K_UDC_H__
  518. +
  519. +/*-------------------------------------------------------------------------*/
  520. +
  521. +#define xprintk(level, fmt, args...) \
  522. +   printk(level "%s: " fmt , driver_name , ## args)
  523. +
  524. +#ifdef DEBUG
  525. +#undef DEBUG
  526. +#define DEBUG(fmt, args...) \
  527. +   xprintk(KERN_DEBUG , fmt , ## args)
  528. +#else
  529. +#define DEBUG(fmt,args...) \
  530. +   do { } while (0)
  531. +#endif /* DEBUG */
  532. +
  533. +#ifdef VERBOSE
  534. +#define VDEBUG DEBUG
  535. +#else
  536. +#define VDEBUG(fmt,args...) \
  537. +   do { } while (0)
  538. +#endif /* VERBOSE */
  539. +
  540. +#define ERROR(fmt,args...) \
  541. +   xprintk(KERN_ERR , fmt , ## args)
  542. +#define INFO(fmt,args...) \
  543. +   xprintk(KERN_INFO , fmt , ## args)
  544. +
  545. +/*-------------------------------------------------------------------------*/
  546. +
  547. +
  548. +#define USB_ID               (MSM_USB_BASE + 0x0000)
  549. +#define USB_HWGENERAL        (MSM_USB_BASE + 0x0004)
  550. +#define USB_HWHOST           (MSM_USB_BASE + 0x0008)
  551. +#define USB_HWDEVICE         (MSM_USB_BASE + 0x000C)
  552. +#define USB_HWTXBUF          (MSM_USB_BASE + 0x0010)
  553. +#define USB_HWRXBUF          (MSM_USB_BASE + 0x0014)
  554. +#define USB_SBUSCFG          (MSM_USB_BASE + 0x0090)
  555. +
  556. +#define USB_CAPLENGTH        (MSM_USB_BASE + 0x0100) /* 8 bit */
  557. +#define USB_HCIVERSION       (MSM_USB_BASE + 0x0102) /* 16 bit */
  558. +#define USB_HCSPARAMS        (MSM_USB_BASE + 0x0104)
  559. +#define USB_HCCPARAMS        (MSM_USB_BASE + 0x0108)
  560. +#define USB_DCIVERSION       (MSM_USB_BASE + 0x0120) /* 16 bit */
  561. +#define USB_USBCMD           (MSM_USB_BASE + 0x0140)
  562. +#define USB_USBSTS           (MSM_USB_BASE + 0x0144)
  563. +#define USB_USBINTR          (MSM_USB_BASE + 0x0148)
  564. +#define USB_FRINDEX          (MSM_USB_BASE + 0x014C)
  565. +#define USB_DEVICEADDR       (MSM_USB_BASE + 0x0154)
  566. +#define USB_ENDPOINTLISTADDR (MSM_USB_BASE + 0x0158)
  567. +#define USB_BURSTSIZE        (MSM_USB_BASE + 0x0160)
  568. +#define USB_TXFILLTUNING     (MSM_USB_BASE + 0x0164)
  569. +#define USB_ULPI_VIEWPORT    (MSM_USB_BASE + 0x0170)
  570. +#define USB_ENDPTNAK         (MSM_USB_BASE + 0x0178)
  571. +#define USB_ENDPTNAKEN       (MSM_USB_BASE + 0x017C)
  572. +#define USB_PORTSC           (MSM_USB_BASE + 0x0184)
  573. +#define USB_OTGSC            (MSM_USB_BASE + 0x01A4)
  574. +#define USB_USBMODE          (MSM_USB_BASE + 0x01A8)
  575. +#define USB_ENDPTSETUPSTAT   (MSM_USB_BASE + 0x01AC)
  576. +#define USB_ENDPTPRIME       (MSM_USB_BASE + 0x01B0)
  577. +#define USB_ENDPTFLUSH       (MSM_USB_BASE + 0x01B4)
  578. +#define USB_ENDPTSTAT        (MSM_USB_BASE + 0x01B8)
  579. +#define USB_ENDPTCOMPLETE    (MSM_USB_BASE + 0x01BC)
  580. +#define USB_ENDPTCTRL(n)     (MSM_USB_BASE + 0x01C0 + (4 * (n)))
  581. +
  582. +
  583. +#define USBCMD_RESET   2
  584. +#define USBCMD_ATTACH  1
  585. +#define USBCMD_ATDTW   (1 << 14)
  586. +
  587. +#define USBMODE_DEVICE 2
  588. +#define USBMODE_HOST   3
  589. +
  590. +struct ept_queue_head {
  591. +    unsigned config;
  592. +    unsigned active; /* read-only */
  593. +
  594. +    unsigned next;
  595. +    unsigned info;
  596. +    unsigned page0;
  597. +    unsigned page1;
  598. +    unsigned page2;
  599. +    unsigned page3;
  600. +    unsigned page4;
  601. +    unsigned reserved_0;
  602. +
  603. +    unsigned char setup_data[8];
  604. +
  605. +    unsigned reserved_1;
  606. +    unsigned reserved_2;
  607. +    unsigned reserved_3;
  608. +    unsigned reserved_4;
  609. +};
  610. +
  611. +#define CONFIG_MAX_PKT(n)     ((n) << 16)
  612. +#define CONFIG_ZLT            (1 << 29)    /* stop on zero-len xfer */
  613. +#define CONFIG_IOS            (1 << 15)    /* IRQ on setup */
  614. +
  615. +struct ept_queue_item {
  616. +    unsigned next;
  617. +    unsigned info;
  618. +    unsigned page0;
  619. +    unsigned page1;
  620. +    unsigned page2;
  621. +    unsigned page3;
  622. +    unsigned page4;
  623. +    unsigned reserved;
  624. +};
  625. +
  626. +#define TERMINATE 1
  627. +
  628. +#define INFO_BYTES(n)         ((n) << 16)
  629. +#define INFO_IOC              (1 << 15)
  630. +#define INFO_ACTIVE           (1 << 7)
  631. +#define INFO_HALTED           (1 << 6)
  632. +#define INFO_BUFFER_ERROR     (1 << 5)
  633. +#define INFO_TXN_ERROR        (1 << 3)
  634. +
  635. +
  636. +#define STS_NAKI          (1 << 16)  /* */
  637. +#define STS_SLI           (1 << 8)   /* R/WC - suspend state entered */
  638. +#define STS_SRI           (1 << 7)   /* R/WC - SOF recv'd */
  639. +#define STS_URI           (1 << 6)   /* R/WC - RESET recv'd - write to clear */
  640. +#define STS_FRI           (1 << 3)   /* R/WC - Frame List Rollover */
  641. +#define STS_PCI           (1 << 2)   /* R/WC - Port Change Detect */
  642. +#define STS_UEI           (1 << 1)   /* R/WC - USB Error */
  643. +#define STS_UI            (1 << 0)   /* R/WC - USB Transaction Complete */
  644. +
  645. +
  646. +/* bits used in all the endpoint status registers */
  647. +#define EPT_TX(n) (1 << ((n) + 16))
  648. +#define EPT_RX(n) (1 << (n))
  649. +
  650. +
  651. +#define CTRL_TXE              (1 << 23)
  652. +#define CTRL_TXR              (1 << 22)
  653. +#define CTRL_TXI              (1 << 21)
  654. +#define CTRL_TXD              (1 << 17)
  655. +#define CTRL_TXS              (1 << 16)
  656. +#define CTRL_RXE              (1 << 7)
  657. +#define CTRL_RXR              (1 << 6)
  658. +#define CTRL_RXI              (1 << 5)
  659. +#define CTRL_RXD              (1 << 1)
  660. +#define CTRL_RXS              (1 << 0)
  661. +
  662. +#define CTRL_TXT_MASK         (3 << 18)
  663. +#define CTRL_TXT_CTRL         (0 << 18)
  664. +#define CTRL_TXT_ISOCH        (1 << 18)
  665. +#define CTRL_TXT_BULK         (2 << 18)
  666. +#define CTRL_TXT_INT          (3 << 18)
  667. +#define CTRL_TXT_EP_TYPE_SHIFT 18
  668. +
  669. +#define CTRL_RXT_MASK         (3 << 2)
  670. +#define CTRL_RXT_CTRL         (0 << 2)
  671. +#define CTRL_RXT_ISOCH        (1 << 2)
  672. +#define CTRL_RXT_BULK         (2 << 2)
  673. +#define CTRL_RXT_INT          (3 << 2)
  674. +#define CTRL_RXT_EP_TYPE_SHIFT 2
  675. +
  676. +#define ULPI_WAKEUP           (1 << 31)
  677. +#define ULPI_RUN              (1 << 30)
  678. +#define ULPI_WRITE            (1 << 29)
  679. +#define ULPI_READ             (0 << 29)
  680. +#define ULPI_STATE_NORMAL     (1 << 27)
  681. +#define ULPI_ADDR(n)          (((n) & 255) << 16)
  682. +#define ULPI_DATA(n)          ((n) & 255)
  683. +#define ULPI_DATA_READ(n)     (((n) >> 8) & 255)
  684. +
  685. +/* USB_PORTSC bits for determining port speed */
  686. +#define PORTSC_PSPD_FS        (0 << 26)
  687. +#define PORTSC_PSPD_LS        (1 << 26)
  688. +#define PORTSC_PSPD_HS        (2 << 26)
  689. +#define PORTSC_PSPD_MASK      (3 << 26)
  690. +/* suspend and remote wakeup */
  691. +#define PORTSC_FPR             (1 << 6)
  692. +#define PORTSC_SUSP            (1 << 7)
  693. +
  694. +/* test mode support */
  695. +#define J_TEST         (0x0100)
  696. +#define K_TEST         (0x0200)
  697. +#define SE0_NAK_TEST       (0x0300)
  698. +#define TST_PKT_TEST       (0x0400)
  699. +#define PORTSC_PTC     (0xf << 16)
  700. +#define PORTSC_PTC_J_STATE (0x01 << 16)
  701. +#define PORTSC_PTC_K_STATE (0x02 << 16)
  702. +#define PORTSC_PTC_SE0_NAK (0x03 << 16)
  703. +#define PORTSC_PTC_TST_PKT (0x04 << 16)
  704. +#endif /* __LINUX_USB_GADGET_MSM72K_UDC_H__ */
  705. diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
  706. index 591ae9f..79717e4 100644
  707. --- a/drivers/usb/gadget/Kconfig
  708. +++ b/drivers/usb/gadget/Kconfig
  709. @@ -509,6 +509,24 @@ config USB_LANGWELL
  710.  #
  711.  # LAST -- dummy/emulated controller
  712.  #
  713. +config USB_GADGET_MSM_72K
  714. +   boolean "MSM 72K Device Controller"
  715. +   depends on ARCH_MSM
  716. +   select USB_GADGET_SELECTED
  717. +   select USB_GADGET_DUALSPEED
  718. +   help
  719. +      USB gadget driver for Qualcomm MSM 72K architecture.
  720. +
  721. +      Say "y" to link the driver statically, or "m" to build a
  722. +      dynamically linked module called "msm72k" and force all
  723. +      gadget drivers to also be dynamically linked.
  724. +
  725. +config USB_MSM_72K
  726. +   tristate
  727. +   depends on USB_GADGET_MSM_72K
  728. +   default USB_GADGET
  729. +   select USB_GADGET_SELECTED
  730. +
  731.  
  732.  config USB_GADGET_DUMMY_HCD
  733.     boolean "Dummy HCD (DEVELOPMENT)"
  734. diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile
  735. index 9bcde11..48ea27a 100644
  736. --- a/drivers/usb/gadget/Makefile
  737. +++ b/drivers/usb/gadget/Makefile
  738. @@ -28,6 +28,7 @@ obj-$(CONFIG_USB_FSL_QE)  += fsl_qe_udc.o
  739.  obj-$(CONFIG_USB_CI13XXX)  += ci13xxx_udc.o
  740.  obj-$(CONFIG_USB_S3C_HSOTG)    += s3c-hsotg.o
  741.  obj-$(CONFIG_USB_LANGWELL) += langwell_udc.o
  742. +obj-$(CONFIG_USB_MSM_72K)       += msm72k_udc.o
  743.  
  744.  #
  745.  # USB gadget drivers
  746. diff --git a/drivers/usb/gadget/gadget_chips.h b/drivers/usb/gadget/gadget_chips.h
  747. index e511fec..a8314ba 100644
  748. --- a/drivers/usb/gadget/gadget_chips.h
  749. +++ b/drivers/usb/gadget/gadget_chips.h
  750. @@ -126,6 +126,12 @@
  751.  #define gadget_is_ci13xxx(g)   0
  752.  #endif
  753.  
  754. +#ifdef CONFIG_USB_GADGET_MSM_72K
  755. +#define gadget_is_msm72k(g)     !strcmp("msm72k_udc", (g)->name)
  756. +#else
  757. +#define gadget_is_msm72k(g)     0
  758. +#endif
  759. +
  760.  // CONFIG_USB_GADGET_SX2
  761.  // CONFIG_USB_GADGET_AU1X00
  762.  // ...
  763. diff --git a/drivers/usb/gadget/msm72k_udc.c b/drivers/usb/gadget/msm72k_udc.c
  764. new file mode 100644
  765. index 0000000..1630cf8
  766. --- /dev/null
  767. +++ b/drivers/usb/gadget/msm72k_udc.c
  768. @@ -0,0 +1,1738 @@
  769. +/*
  770. + * Driver for HighSpeed USB Client Controller in MSM7K
  771. + *
  772. + * Copyright (C) 2008 Google, Inc.
  773. + * Author: Mike Lockwood <lockwood@android.com>
  774. + *         Brian Swetland <swetland@google.com>
  775. + *
  776. + * This software is licensed under the terms of the GNU General Public
  777. + * License version 2, as published by the Free Software Foundation, and
  778. + * may be copied, distributed, and modified under those terms.
  779. + *
  780. + * This program is distributed in the hope that it will be useful,
  781. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  782. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  783. + * GNU General Public License for more details.
  784. + *
  785. + */
  786. +
  787. +#include <linux/init.h>
  788. +#include <linux/module.h>
  789. +#include <linux/kernel.h>
  790. +#include <linux/list.h>
  791. +
  792. +#include <linux/delay.h>
  793. +#include <linux/interrupt.h>
  794. +#include <linux/dma-mapping.h>
  795. +#include <linux/dmapool.h>
  796. +#include <linux/platform_device.h>
  797. +#include <linux/debugfs.h>
  798. +#include <linux/workqueue.h>
  799. +#include <linux/clk.h>
  800. +
  801. +#include <linux/usb/ch9.h>
  802. +#include <linux/usb/gadget.h>
  803. +#include <linux/io.h>
  804. +
  805. +#include <asm/mach-types.h>
  806. +
  807. +#include <mach/board.h>
  808. +#include <mach/msm_hsusb.h>
  809. +#include <linux/device.h>
  810. +#include <mach/msm_hsusb_hw.h>
  811. +
  812. +static const char driver_name[] = "msm72k_udc";
  813. +
  814. +/* #define DEBUG */
  815. +/* #define VERBOSE */
  816. +
  817. +#define MSM_USB_BASE ((unsigned) ui->addr)
  818. +
  819. +#define    DRIVER_DESC     "MSM 72K USB Peripheral Controller"
  820. +
  821. +#define EPT_FLAG_IN        0x0001
  822. +
  823. +#define SETUP_BUF_SIZE      4096
  824. +
  825. +
  826. +static const char *const ep_name[] = {
  827. +   "ep0out", "ep1out", "ep2out", "ep3out",
  828. +   "ep4out", "ep5out", "ep6out", "ep7out",
  829. +   "ep8out", "ep9out", "ep10out", "ep11out",
  830. +   "ep12out", "ep13out", "ep14out", "ep15out",
  831. +   "ep0in", "ep1in", "ep2in", "ep3in",
  832. +   "ep4in", "ep5in", "ep6in", "ep7in",
  833. +   "ep8in", "ep9in", "ep10in", "ep11in",
  834. +   "ep12in", "ep13in", "ep14in", "ep15in"
  835. +};
  836. +
  837. +/* current state of VBUS */
  838. +static int vbus;
  839. +
  840. +struct msm_request {
  841. +   struct usb_request req;
  842. +
  843. +   /* saved copy of req.complete */
  844. +   void    (*gadget_complete)(struct usb_ep *ep,
  845. +                   struct usb_request *req);
  846. +
  847. +
  848. +   struct usb_info *ui;
  849. +   struct msm_request *next;
  850. +
  851. +   unsigned busy:1;
  852. +   unsigned live:1;
  853. +   unsigned alloced:1;
  854. +   unsigned dead:1;
  855. +
  856. +   dma_addr_t dma;
  857. +   dma_addr_t item_dma;
  858. +
  859. +   struct ept_queue_item *item;
  860. +};
  861. +
  862. +#define to_msm_request(r) container_of(r, struct msm_request, req)
  863. +#define to_msm_endpoint(r) container_of(r, struct msm_endpoint, ep)
  864. +
  865. +struct msm_endpoint {
  866. +   struct usb_ep ep;
  867. +   struct usb_info *ui;
  868. +   struct msm_request *req; /* head of pending requests */
  869. +   struct msm_request *last;
  870. +   unsigned flags;
  871. +
  872. +   /* bit number (0-31) in various status registers
  873. +   ** as well as the index into the usb_info's array
  874. +   ** of all endpoints
  875. +   */
  876. +   unsigned char bit;
  877. +   unsigned char num;
  878. +
  879. +   /* pointers to DMA transfer list area */
  880. +   /* these are allocated from the usb_info dma space */
  881. +   struct ept_queue_head *head;
  882. +};
  883. +
  884. +static void usb_do_work(struct work_struct *w);
  885. +
  886. +
  887. +#define USB_STATE_IDLE    0
  888. +#define USB_STATE_ONLINE  1
  889. +#define USB_STATE_OFFLINE 2
  890. +
  891. +#define USB_FLAG_START          0x0001
  892. +#define USB_FLAG_VBUS_ONLINE    0x0002
  893. +#define USB_FLAG_VBUS_OFFLINE   0x0004
  894. +#define USB_FLAG_RESET          0x0008
  895. +
  896. +struct usb_info {
  897. +   /* lock for register/queue/device state changes */
  898. +   spinlock_t lock;
  899. +
  900. +   /* single request used for handling setup transactions */
  901. +   struct usb_request *setup_req;
  902. +
  903. +   struct platform_device *pdev;
  904. +   int irq;
  905. +   void *addr;
  906. +
  907. +   unsigned state;
  908. +   unsigned flags;
  909. +
  910. +   unsigned    online:1;
  911. +   unsigned    running:1;
  912. +
  913. +   struct dma_pool *pool;
  914. +
  915. +   /* dma page to back the queue heads and items */
  916. +   unsigned char *buf;
  917. +   dma_addr_t dma;
  918. +
  919. +   struct ept_queue_head *head;
  920. +
  921. +   /* used for allocation */
  922. +   unsigned next_item;
  923. +   unsigned next_ifc_num;
  924. +
  925. +   /* endpoints are ordered based on their status bits,
  926. +   ** so they are OUT0, OUT1, ... OUT15, IN0, IN1, ... IN15
  927. +   */
  928. +   struct msm_endpoint ept[32];
  929. +
  930. +   int *phy_init_seq;
  931. +   void (*phy_reset)(void);
  932. +
  933. +   /* for notification when USB is connected or disconnected */
  934. +   void (*usb_connected)(int);
  935. +
  936. +   struct work_struct work;
  937. +   unsigned phy_status;
  938. +   unsigned phy_fail_count;
  939. +
  940. +   struct usb_gadget       gadget;
  941. +   struct usb_gadget_driver    *driver;
  942. +
  943. +#define ep0out ept[0]
  944. +#define ep0in  ept[16]
  945. +
  946. +   struct clk *clk;
  947. +   struct clk *pclk;
  948. +
  949. +   unsigned int ep0_dir;
  950. +   u16 test_mode;
  951. +
  952. +   u8 remote_wakeup;
  953. +};
  954. +
  955. +static const struct usb_ep_ops msm72k_ep_ops;
  956. +
  957. +
  958. +static int msm72k_pullup(struct usb_gadget *_gadget, int is_active);
  959. +static int msm72k_set_halt(struct usb_ep *_ep, int value);
  960. +static void flush_endpoint(struct msm_endpoint *ept);
  961. +
  962. +static int usb_ep_get_stall(struct msm_endpoint *ept)
  963. +{
  964. +   unsigned int n;
  965. +   struct usb_info *ui = ept->ui;
  966. +
  967. +   n = readl(USB_ENDPTCTRL(ept->num));
  968. +   if (ept->flags & EPT_FLAG_IN)
  969. +       return (CTRL_TXS & n) ? 1 : 0;
  970. +   else
  971. +       return (CTRL_RXS & n) ? 1 : 0;
  972. +}
  973. +
  974. +#if 0
  975. +static unsigned ulpi_read(struct usb_info *ui, unsigned reg)
  976. +{
  977. +   unsigned timeout = 100000;
  978. +
  979. +   /* initiate read operation */
  980. +   writel(ULPI_RUN | ULPI_READ | ULPI_ADDR(reg),
  981. +          USB_ULPI_VIEWPORT);
  982. +
  983. +   /* wait for completion */
  984. +   while ((readl(USB_ULPI_VIEWPORT) & ULPI_RUN) && (--timeout))
  985. +       ;
  986. +
  987. +   if (timeout == 0) {
  988. +       ERROR("ulpi_read: timeout %08x\n", readl(USB_ULPI_VIEWPORT));
  989. +       return 0xffffffff;
  990. +   }
  991. +   return ULPI_DATA_READ(readl(USB_ULPI_VIEWPORT));
  992. +}
  993. +#endif
  994. +
  995. +static void ulpi_write(struct usb_info *ui, unsigned val, unsigned reg)
  996. +{
  997. +   unsigned timeout = 10000;
  998. +
  999. +   /* initiate write operation */
  1000. +   writel(ULPI_RUN | ULPI_WRITE |
  1001. +          ULPI_ADDR(reg) | ULPI_DATA(val),
  1002. +          USB_ULPI_VIEWPORT);
  1003. +
  1004. +   /* wait for completion */
  1005. +   while ((readl(USB_ULPI_VIEWPORT) & ULPI_RUN) && (--timeout))
  1006. +       ;
  1007. +
  1008. +   if (timeout == 0)
  1009. +       ERROR("ulpi_write: timeout\n");
  1010. +}
  1011. +
  1012. +static void ulpi_init(struct usb_info *ui)
  1013. +{
  1014. +   int *seq = ui->phy_init_seq;
  1015. +
  1016. +   if (!seq)
  1017. +       return;
  1018. +
  1019. +   while (seq[0] >= 0) {
  1020. +       INFO("ulpi: write 0x%02x to 0x%02x\n", seq[0], seq[1]);
  1021. +       ulpi_write(ui, seq[0], seq[1]);
  1022. +       seq += 2;
  1023. +   }
  1024. +}
  1025. +
  1026. +static void init_endpoints(struct usb_info *ui)
  1027. +{
  1028. +   unsigned n;
  1029. +
  1030. +   for (n = 0; n < 32; n++) {
  1031. +       struct msm_endpoint *ept = ui->ept + n;
  1032. +
  1033. +       ept->ui = ui;
  1034. +       ept->bit = n;
  1035. +       ept->num = n & 15;
  1036. +       ept->ep.name = ep_name[n];
  1037. +       ept->ep.ops = &msm72k_ep_ops;
  1038. +
  1039. +       if (ept->bit > 15) {
  1040. +           /* IN endpoint */
  1041. +           ept->head = ui->head + (ept->num << 1) + 1;
  1042. +           ept->flags = EPT_FLAG_IN;
  1043. +       } else {
  1044. +           /* OUT endpoint */
  1045. +           ept->head = ui->head + (ept->num << 1);
  1046. +           ept->flags = 0;
  1047. +       }
  1048. +
  1049. +   }
  1050. +}
  1051. +
  1052. +static void config_ept(struct msm_endpoint *ept)
  1053. +{
  1054. +   unsigned cfg = CONFIG_MAX_PKT(ept->ep.maxpacket) | CONFIG_ZLT;
  1055. +
  1056. +   if (ept->bit == 0)
  1057. +       /* ep0 out needs interrupt-on-setup */
  1058. +       cfg |= CONFIG_IOS;
  1059. +
  1060. +   ept->head->config = cfg;
  1061. +   ept->head->next = TERMINATE;
  1062. +
  1063. +   if (ept->ep.maxpacket)
  1064. +       INFO("ept #%d %s max:%d head:%p bit:%d\n",
  1065. +           ept->num, (ept->flags & EPT_FLAG_IN) ? "in" : "out",
  1066. +           ept->ep.maxpacket, ept->head, ept->bit);
  1067. +}
  1068. +
  1069. +static void configure_endpoints(struct usb_info *ui)
  1070. +{
  1071. +   unsigned n;
  1072. +
  1073. +   for (n = 0; n < 32; n++)
  1074. +       config_ept(ui->ept + n);
  1075. +}
  1076. +
  1077. +struct usb_request *usb_ept_alloc_req(struct msm_endpoint *ept,
  1078. +           unsigned bufsize, gfp_t gfp_flags)
  1079. +{
  1080. +   struct usb_info *ui = ept->ui;
  1081. +   struct msm_request *req;
  1082. +
  1083. +   req = kzalloc(sizeof(*req), gfp_flags);
  1084. +   if (!req)
  1085. +       goto fail1;
  1086. +
  1087. +   req->item = dma_pool_alloc(ui->pool, gfp_flags, &req->item_dma);
  1088. +   if (!req->item)
  1089. +       goto fail2;
  1090. +
  1091. +   if (bufsize) {
  1092. +       req->req.buf = kmalloc(bufsize, gfp_flags);
  1093. +       if (!req->req.buf)
  1094. +           goto fail3;
  1095. +       req->alloced = 1;
  1096. +   }
  1097. +
  1098. +   return &req->req;
  1099. +
  1100. +fail3:
  1101. +   dma_pool_free(ui->pool, req->item, req->item_dma);
  1102. +fail2:
  1103. +   kfree(req);
  1104. +fail1:
  1105. +   return 0;
  1106. +}
  1107. +
  1108. +static void do_free_req(struct usb_info *ui, struct msm_request *req)
  1109. +{
  1110. +   if (req->alloced)
  1111. +       kfree(req->req.buf);
  1112. +
  1113. +   dma_pool_free(ui->pool, req->item, req->item_dma);
  1114. +   kfree(req);
  1115. +}
  1116. +
  1117. +
  1118. +static void usb_ept_enable(struct msm_endpoint *ept, int yes,
  1119. +       unsigned char ep_type)
  1120. +{
  1121. +   struct usb_info *ui = ept->ui;
  1122. +   int in = ept->flags & EPT_FLAG_IN;
  1123. +   unsigned n;
  1124. +
  1125. +   n = readl(USB_ENDPTCTRL(ept->num));
  1126. +
  1127. +   if (in) {
  1128. +       if (yes) {
  1129. +           n = (n & (~CTRL_TXT_MASK)) |
  1130. +               (ep_type << CTRL_TXT_EP_TYPE_SHIFT);
  1131. +           n |= CTRL_TXE | CTRL_TXR;
  1132. +       } else
  1133. +           n &= (~CTRL_TXE);
  1134. +   } else {
  1135. +       if (yes) {
  1136. +           n = (n & (~CTRL_RXT_MASK)) |
  1137. +               (ep_type << CTRL_RXT_EP_TYPE_SHIFT);
  1138. +           n |= CTRL_RXE | CTRL_RXR;
  1139. +       } else
  1140. +           n &= ~(CTRL_RXE);
  1141. +   }
  1142. +   writel(n, USB_ENDPTCTRL(ept->num));
  1143. +
  1144. +#if 1
  1145. +   INFO("ept %d %s %s\n",
  1146. +          ept->num, in ? "in" : "out", yes ? "enabled" : "disabled");
  1147. +#endif
  1148. +}
  1149. +
  1150. +static void usb_ept_start(struct msm_endpoint *ept)
  1151. +{
  1152. +   struct usb_info *ui = ept->ui;
  1153. +   struct msm_request *req = ept->req;
  1154. +
  1155. +   BUG_ON(req->live);
  1156. +
  1157. +   /* link the hw queue head to the request's transaction item */
  1158. +   ept->head->next = req->item_dma;
  1159. +   ept->head->info = 0;
  1160. +
  1161. +   /* start the endpoint */
  1162. +   writel(1 << ept->bit, USB_ENDPTPRIME);
  1163. +
  1164. +   /* mark this chain of requests as live */
  1165. +   while (req) {
  1166. +       req->live = 1;
  1167. +       req = req->next;
  1168. +   }
  1169. +}
  1170. +
  1171. +int usb_ept_queue_xfer(struct msm_endpoint *ept, struct usb_request *_req)
  1172. +{
  1173. +   unsigned long flags;
  1174. +   struct msm_request *req = to_msm_request(_req);
  1175. +   struct msm_request *last;
  1176. +   struct usb_info *ui = ept->ui;
  1177. +   struct ept_queue_item *item = req->item;
  1178. +   unsigned length = req->req.length;
  1179. +
  1180. +   if (length > 0x4000)
  1181. +       return -EMSGSIZE;
  1182. +
  1183. +   spin_lock_irqsave(&ui->lock, flags);
  1184. +
  1185. +   if (req->busy) {
  1186. +       req->req.status = -EBUSY;
  1187. +       spin_unlock_irqrestore(&ui->lock, flags);
  1188. +       INFO("usb_ept_queue_xfer() tried to queue busy request\n");
  1189. +       return -EBUSY;
  1190. +   }
  1191. +
  1192. +   if (!ui->online && (ept->num != 0)) {
  1193. +       req->req.status = -ESHUTDOWN;
  1194. +       spin_unlock_irqrestore(&ui->lock, flags);
  1195. +       INFO("usb_ept_queue_xfer() called while offline\n");
  1196. +       return -ESHUTDOWN;
  1197. +   }
  1198. +
  1199. +   req->busy = 1;
  1200. +   req->live = 0;
  1201. +   req->next = 0;
  1202. +   req->req.status = -EBUSY;
  1203. +
  1204. +   req->dma = dma_map_single(NULL, req->req.buf, length,
  1205. +                 (ept->flags & EPT_FLAG_IN) ?
  1206. +                 DMA_TO_DEVICE : DMA_FROM_DEVICE);
  1207. +
  1208. +   /* prepare the transaction descriptor item for the hardware */
  1209. +   item->next = TERMINATE;
  1210. +   item->info = INFO_BYTES(length) | INFO_IOC | INFO_ACTIVE;
  1211. +   item->page0 = req->dma;
  1212. +   item->page1 = (req->dma + 0x1000) & 0xfffff000;
  1213. +   item->page2 = (req->dma + 0x2000) & 0xfffff000;
  1214. +   item->page3 = (req->dma + 0x3000) & 0xfffff000;
  1215. +
  1216. +   /* Add the new request to the end of the queue */
  1217. +   last = ept->last;
  1218. +   if (last) {
  1219. +       /* Already requests in the queue. add us to the
  1220. +        * end, but let the completion interrupt actually
  1221. +        * start things going, to avoid hw issues
  1222. +        */
  1223. +       last->next = req;
  1224. +
  1225. +       /* only modify the hw transaction next pointer if
  1226. +        * that request is not live
  1227. +        */
  1228. +       if (!last->live)
  1229. +           last->item->next = req->item_dma;
  1230. +   } else {
  1231. +       /* queue was empty -- kick the hardware */
  1232. +       ept->req = req;
  1233. +       usb_ept_start(ept);
  1234. +   }
  1235. +   ept->last = req;
  1236. +
  1237. +   spin_unlock_irqrestore(&ui->lock, flags);
  1238. +   return 0;
  1239. +}
  1240. +
  1241. +/* --- endpoint 0 handling --- */
  1242. +
  1243. +static void ep0_complete(struct usb_ep *ep, struct usb_request *req)
  1244. +{
  1245. +   struct msm_request *r = to_msm_request(req);
  1246. +   struct msm_endpoint *ept = to_msm_endpoint(ep);
  1247. +   struct usb_info *ui = ept->ui;
  1248. +
  1249. +   req->complete = r->gadget_complete;
  1250. +   r->gadget_complete = 0;
  1251. +   if  (req->complete)
  1252. +       req->complete(&ui->ep0in.ep, req);
  1253. +}
  1254. +
  1255. +static void ep0_queue_ack_complete(struct usb_ep *ep, struct usb_request *req)
  1256. +{
  1257. +   struct msm_endpoint *ept = to_msm_endpoint(ep);
  1258. +
  1259. +   /* queue up the receive of the ACK response from the host */
  1260. +   if (req->status == 0) {
  1261. +       struct usb_info *ui = ept->ui;
  1262. +       req->length = 0;
  1263. +       req->complete = ep0_complete;
  1264. +       if (ui->ep0_dir == USB_DIR_IN)
  1265. +           usb_ept_queue_xfer(&ui->ep0out, req);
  1266. +       else
  1267. +           usb_ept_queue_xfer(&ui->ep0in, req);
  1268. +   } else
  1269. +       ep0_complete(ep, req);
  1270. +}
  1271. +
  1272. +static void ep0_setup_ack_complete(struct usb_ep *ep, struct usb_request *req)
  1273. +{
  1274. +   struct msm_endpoint *ept = to_msm_endpoint(ep);
  1275. +   struct usb_info *ui = ept->ui;
  1276. +   unsigned int temp;
  1277. +
  1278. +   if (!ui->test_mode)
  1279. +       return;
  1280. +
  1281. +   switch (ui->test_mode) {
  1282. +   case J_TEST:
  1283. +       pr_info("usb electrical test mode: (J)\n");
  1284. +       temp = readl(USB_PORTSC) & (~PORTSC_PTC);
  1285. +       writel(temp | PORTSC_PTC_J_STATE, USB_PORTSC);
  1286. +       break;
  1287. +
  1288. +   case K_TEST:
  1289. +       pr_info("usb electrical test mode: (K)\n");
  1290. +       temp = readl(USB_PORTSC) & (~PORTSC_PTC);
  1291. +       writel(temp | PORTSC_PTC_K_STATE, USB_PORTSC);
  1292. +       break;
  1293. +
  1294. +   case SE0_NAK_TEST:
  1295. +       pr_info("usb electrical test mode: (SE0-NAK)\n");
  1296. +       temp = readl(USB_PORTSC) & (~PORTSC_PTC);
  1297. +       writel(temp | PORTSC_PTC_SE0_NAK, USB_PORTSC);
  1298. +       break;
  1299. +
  1300. +   case TST_PKT_TEST:
  1301. +       pr_info("usb electrical test mode: (TEST_PKT)\n");
  1302. +       temp = readl(USB_PORTSC) & (~PORTSC_PTC);
  1303. +       writel(temp | PORTSC_PTC_TST_PKT, USB_PORTSC);
  1304. +       break;
  1305. +   }
  1306. +}
  1307. +
  1308. +static void ep0_setup_ack(struct usb_info *ui)
  1309. +{
  1310. +   struct usb_request *req = ui->setup_req;
  1311. +   req->length = 0;
  1312. +   req->complete = ep0_setup_ack_complete;
  1313. +   usb_ept_queue_xfer(&ui->ep0in, req);
  1314. +}
  1315. +
  1316. +static void ep0_setup_stall(struct usb_info *ui)
  1317. +{
  1318. +   writel((1<<16) | (1<<0), USB_ENDPTCTRL(0));
  1319. +}
  1320. +
  1321. +static void ep0_setup_send(struct usb_info *ui, unsigned length)
  1322. +{
  1323. +   struct usb_request *req = ui->setup_req;
  1324. +   struct msm_request *r = to_msm_request(req);
  1325. +   struct msm_endpoint *ept = &ui->ep0in;
  1326. +
  1327. +   req->length = length;
  1328. +   req->complete = ep0_queue_ack_complete;
  1329. +   r->gadget_complete = 0;
  1330. +   usb_ept_queue_xfer(ept, req);
  1331. +}
  1332. +
  1333. +static void handle_setup(struct usb_info *ui)
  1334. +{
  1335. +   struct usb_ctrlrequest ctl;
  1336. +   struct usb_request *req = ui->setup_req;
  1337. +   int ret;
  1338. +
  1339. +   memcpy(&ctl, ui->ep0out.head->setup_data, sizeof(ctl));
  1340. +   writel(EPT_RX(0), USB_ENDPTSETUPSTAT);
  1341. +
  1342. +   if (ctl.bRequestType & USB_DIR_IN)
  1343. +       ui->ep0_dir = USB_DIR_IN;
  1344. +   else
  1345. +       ui->ep0_dir = USB_DIR_OUT;
  1346. +
  1347. +   /* any pending ep0 transactions must be canceled */
  1348. +   flush_endpoint(&ui->ep0out);
  1349. +   flush_endpoint(&ui->ep0in);
  1350. +
  1351. +   INFO("setup: type=%02x req=%02x val=%04x idx=%04x len=%04x\n",
  1352. +          ctl.bRequestType, ctl.bRequest, ctl.wValue,
  1353. +          ctl.wIndex, ctl.wLength);
  1354. +
  1355. +   if ((ctl.bRequestType & (USB_DIR_IN | USB_TYPE_MASK)) ==
  1356. +                   (USB_DIR_IN | USB_TYPE_STANDARD)) {
  1357. +       if (ctl.bRequest == USB_REQ_GET_STATUS) {
  1358. +           if (ctl.wLength != 2)
  1359. +               goto stall;
  1360. +           switch (ctl.bRequestType & USB_RECIP_MASK) {
  1361. +           case USB_RECIP_ENDPOINT:
  1362. +           {
  1363. +               struct msm_endpoint *ept;
  1364. +               unsigned num =
  1365. +                   ctl.wIndex & USB_ENDPOINT_NUMBER_MASK;
  1366. +               u16 temp = 0;
  1367. +
  1368. +               if (num == 0) {
  1369. +                   memset(req->buf, 0, 2);
  1370. +                   break;
  1371. +               }
  1372. +               if (ctl.wIndex & USB_ENDPOINT_DIR_MASK)
  1373. +                   num += 16;
  1374. +               ept = &ui->ep0out + num;
  1375. +               temp = usb_ep_get_stall(ept);
  1376. +               temp = temp << USB_ENDPOINT_HALT;
  1377. +               memcpy(req->buf, &temp, 2);
  1378. +               break;
  1379. +           }
  1380. +           case USB_RECIP_DEVICE:
  1381. +           {
  1382. +               u16 temp = 0;
  1383. +
  1384. +               temp = 1 << USB_DEVICE_SELF_POWERED;
  1385. +               temp |= (ui->remote_wakeup <<
  1386. +                       USB_DEVICE_REMOTE_WAKEUP);
  1387. +               memcpy(req->buf, &temp, 2);
  1388. +               break;
  1389. +           }
  1390. +           case USB_RECIP_INTERFACE:
  1391. +               memset(req->buf, 0, 2);
  1392. +               break;
  1393. +           default:
  1394. +               goto stall;
  1395. +           }
  1396. +           ep0_setup_send(ui, 2);
  1397. +           return;
  1398. +       }
  1399. +   }
  1400. +   if (ctl.bRequestType ==
  1401. +           (USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_ENDPOINT)) {
  1402. +       if ((ctl.bRequest == USB_REQ_CLEAR_FEATURE) ||
  1403. +               (ctl.bRequest == USB_REQ_SET_FEATURE)) {
  1404. +           if ((ctl.wValue == 0) && (ctl.wLength == 0)) {
  1405. +               unsigned num = ctl.wIndex & 0x0f;
  1406. +
  1407. +               if (num != 0) {
  1408. +                   struct msm_endpoint *ept;
  1409. +
  1410. +                   if (ctl.wIndex & 0x80)
  1411. +                       num += 16;
  1412. +                   ept = &ui->ep0out + num;
  1413. +
  1414. +                   if (ctl.bRequest == USB_REQ_SET_FEATURE)
  1415. +                       msm72k_set_halt(&ept->ep, 1);
  1416. +                   else
  1417. +                       msm72k_set_halt(&ept->ep, 0);
  1418. +               }
  1419. +               goto ack;
  1420. +           }
  1421. +       }
  1422. +   }
  1423. +   if (ctl.bRequestType == (USB_DIR_OUT | USB_TYPE_STANDARD)) {
  1424. +       if (ctl.bRequest == USB_REQ_SET_CONFIGURATION)
  1425. +           ui->online = !!ctl.wValue;
  1426. +       else if (ctl.bRequest == USB_REQ_SET_ADDRESS) {
  1427. +           /* write address delayed (will take effect
  1428. +           ** after the next IN txn)
  1429. +           */
  1430. +           writel((ctl.wValue << 25) | (1 << 24), USB_DEVICEADDR);
  1431. +           goto ack;
  1432. +       } else if (ctl.bRequest == USB_REQ_SET_FEATURE) {
  1433. +           switch (ctl.wValue) {
  1434. +           case USB_DEVICE_TEST_MODE:
  1435. +               switch (ctl.wIndex) {
  1436. +               case J_TEST:
  1437. +               case K_TEST:
  1438. +               case SE0_NAK_TEST:
  1439. +               case TST_PKT_TEST:
  1440. +                   ui->test_mode = ctl.wIndex;
  1441. +                   goto ack;
  1442. +               }
  1443. +               goto stall;
  1444. +           case USB_DEVICE_REMOTE_WAKEUP:
  1445. +               ui->remote_wakeup = 1;
  1446. +               goto ack;
  1447. +           }
  1448. +       } else if ((ctl.bRequest == USB_REQ_CLEAR_FEATURE) &&
  1449. +               (ctl.wValue == USB_DEVICE_REMOTE_WAKEUP)) {
  1450. +           ui->remote_wakeup = 0;
  1451. +           goto ack;
  1452. +       }
  1453. +   }
  1454. +
  1455. +   /* delegate if we get here */
  1456. +   if (ui->driver) {
  1457. +       ret = ui->driver->setup(&ui->gadget, &ctl);
  1458. +       if (ret >= 0)
  1459. +           return;
  1460. +   }
  1461. +
  1462. +stall:
  1463. +   /* stall ep0 on error */
  1464. +   ep0_setup_stall(ui);
  1465. +   return;
  1466. +
  1467. +ack:
  1468. +   ep0_setup_ack(ui);
  1469. +}
  1470. +
  1471. +static void handle_endpoint(struct usb_info *ui, unsigned bit)
  1472. +{
  1473. +   struct msm_endpoint *ept = ui->ept + bit;
  1474. +   struct msm_request *req;
  1475. +   unsigned long flags;
  1476. +   unsigned info;
  1477. +
  1478. +   /*
  1479. +   INFO("handle_endpoint() %d %s req=%p(%08x)\n",
  1480. +       ept->num, (ept->flags & EPT_FLAG_IN) ? "in" : "out",
  1481. +       ept->req, ept->req ? ept->req->item_dma : 0);
  1482. +   */
  1483. +
  1484. +   /* expire all requests that are no longer active */
  1485. +   spin_lock_irqsave(&ui->lock, flags);
  1486. +   while ((req = ept->req)) {
  1487. +       info = req->item->info;
  1488. +
  1489. +       /* if we've processed all live requests, time to
  1490. +        * restart the hardware on the next non-live request
  1491. +        */
  1492. +       if (!req->live) {
  1493. +           usb_ept_start(ept);
  1494. +           break;
  1495. +       }
  1496. +
  1497. +       /* if the transaction is still in-flight, stop here */
  1498. +       if (info & INFO_ACTIVE)
  1499. +           break;
  1500. +
  1501. +       /* advance ept queue to the next request */
  1502. +       ept->req = req->next;
  1503. +       if (ept->req == 0)
  1504. +           ept->last = 0;
  1505. +
  1506. +       dma_unmap_single(NULL, req->dma, req->req.length,
  1507. +                (ept->flags & EPT_FLAG_IN) ?
  1508. +                DMA_TO_DEVICE : DMA_FROM_DEVICE);
  1509. +
  1510. +       if (info & (INFO_HALTED | INFO_BUFFER_ERROR | INFO_TXN_ERROR)) {
  1511. +           /* XXX pass on more specific error code */
  1512. +           req->req.status = -EIO;
  1513. +           req->req.actual = 0;
  1514. +           INFO("msm72k_udc: ept %d %s error. info=%08x\n",
  1515. +                  ept->num,
  1516. +                  (ept->flags & EPT_FLAG_IN) ? "in" : "out",
  1517. +                  info);
  1518. +       } else {
  1519. +           req->req.status = 0;
  1520. +           req->req.actual =
  1521. +               req->req.length - ((info >> 16) & 0x7FFF);
  1522. +       }
  1523. +       req->busy = 0;
  1524. +       req->live = 0;
  1525. +       if (req->dead)
  1526. +           do_free_req(ui, req);
  1527. +
  1528. +       if (req->req.complete) {
  1529. +           spin_unlock_irqrestore(&ui->lock, flags);
  1530. +           req->req.complete(&ept->ep, &req->req);
  1531. +           spin_lock_irqsave(&ui->lock, flags);
  1532. +       }
  1533. +   }
  1534. +   spin_unlock_irqrestore(&ui->lock, flags);
  1535. +}
  1536. +
  1537. +static void flush_endpoint_hw(struct usb_info *ui, unsigned bits)
  1538. +{
  1539. +   /* flush endpoint, canceling transactions
  1540. +   ** - this can take a "large amount of time" (per databook)
  1541. +   ** - the flush can fail in some cases, thus we check STAT
  1542. +   **   and repeat if we're still operating
  1543. +   **   (does the fact that this doesn't use the tripwire matter?!)
  1544. +   */
  1545. +   do {
  1546. +       writel(bits, USB_ENDPTFLUSH);
  1547. +       while (readl(USB_ENDPTFLUSH) & bits)
  1548. +           udelay(100);
  1549. +   } while (readl(USB_ENDPTSTAT) & bits);
  1550. +}
  1551. +
  1552. +static void flush_endpoint_sw(struct msm_endpoint *ept)
  1553. +{
  1554. +   struct usb_info *ui = ept->ui;
  1555. +   struct msm_request *req;
  1556. +   unsigned long flags;
  1557. +
  1558. +   /* inactive endpoints have nothing to do here */
  1559. +   if (ept->ep.maxpacket == 0)
  1560. +       return;
  1561. +
  1562. +   /* put the queue head in a sane state */
  1563. +   ept->head->info = 0;
  1564. +   ept->head->next = TERMINATE;
  1565. +
  1566. +   /* cancel any pending requests */
  1567. +   spin_lock_irqsave(&ui->lock, flags);
  1568. +   req = ept->req;
  1569. +   ept->req = 0;
  1570. +   ept->last = 0;
  1571. +   while (req != 0) {
  1572. +       req->busy = 0;
  1573. +       req->live = 0;
  1574. +       req->req.status = -ECONNRESET;
  1575. +       req->req.actual = 0;
  1576. +       if (req->req.complete) {
  1577. +           spin_unlock_irqrestore(&ui->lock, flags);
  1578. +           req->req.complete(&ept->ep, &req->req);
  1579. +           spin_lock_irqsave(&ui->lock, flags);
  1580. +       }
  1581. +       if (req->dead)
  1582. +           do_free_req(ui, req);
  1583. +       req = req->next;
  1584. +   }
  1585. +   spin_unlock_irqrestore(&ui->lock, flags);
  1586. +}
  1587. +
  1588. +static void flush_endpoint(struct msm_endpoint *ept)
  1589. +{
  1590. +   flush_endpoint_hw(ept->ui, (1 << ept->bit));
  1591. +   flush_endpoint_sw(ept);
  1592. +}
  1593. +
  1594. +static void flush_all_endpoints(struct usb_info *ui)
  1595. +{
  1596. +   unsigned n;
  1597. +
  1598. +   flush_endpoint_hw(ui, 0xffffffff);
  1599. +
  1600. +   for (n = 0; n < 32; n++)
  1601. +       flush_endpoint_sw(ui->ept + n);
  1602. +}
  1603. +
  1604. +
  1605. +static irqreturn_t usb_interrupt(int irq, void *data)
  1606. +{
  1607. +   struct usb_info *ui = data;
  1608. +   unsigned n;
  1609. +
  1610. +   n = readl(USB_USBSTS);
  1611. +   writel(n, USB_USBSTS);
  1612. +
  1613. +   /* somehow we got an IRQ while in the reset sequence: ignore it */
  1614. +   if (ui->running == 0)
  1615. +       return IRQ_HANDLED;
  1616. +
  1617. +   if (n & STS_PCI) {
  1618. +       switch (readl(USB_PORTSC) & PORTSC_PSPD_MASK) {
  1619. +       case PORTSC_PSPD_FS:
  1620. +           INFO("msm72k_udc: portchange USB_SPEED_FULL\n");
  1621. +           ui->gadget.speed = USB_SPEED_FULL;
  1622. +           break;
  1623. +       case PORTSC_PSPD_LS:
  1624. +           INFO("msm72k_udc: portchange USB_SPEED_LOW\n");
  1625. +           ui->gadget.speed = USB_SPEED_LOW;
  1626. +           break;
  1627. +       case PORTSC_PSPD_HS:
  1628. +           INFO("msm72k_udc: portchange USB_SPEED_HIGH\n");
  1629. +           ui->gadget.speed = USB_SPEED_HIGH;
  1630. +           break;
  1631. +       }
  1632. +   }
  1633. +
  1634. +   if (n & STS_URI) {
  1635. +       INFO("msm72k_udc: reset\n");
  1636. +
  1637. +       writel(readl(USB_ENDPTSETUPSTAT), USB_ENDPTSETUPSTAT);
  1638. +       writel(readl(USB_ENDPTCOMPLETE), USB_ENDPTCOMPLETE);
  1639. +       writel(0xffffffff, USB_ENDPTFLUSH);
  1640. +       writel(0, USB_ENDPTCTRL(1));
  1641. +
  1642. +       if (ui->online != 0) {
  1643. +           /* marking us offline will cause ept queue attempts
  1644. +           ** to fail
  1645. +           */
  1646. +           ui->online = 0;
  1647. +
  1648. +           flush_all_endpoints(ui);
  1649. +
  1650. +           /* XXX: we can't seem to detect going offline,
  1651. +            * XXX:  so deconfigure on reset for the time being
  1652. +            */
  1653. +           if (ui->driver) {
  1654. +               printk(KERN_INFO "usb: notify offline\n");
  1655. +               ui->driver->disconnect(&ui->gadget);
  1656. +           }
  1657. +       }
  1658. +   }
  1659. +
  1660. +   if (n & STS_SLI)
  1661. +       INFO("msm72k_udc: suspend\n");
  1662. +
  1663. +   if (n & STS_UI) {
  1664. +       n = readl(USB_ENDPTSETUPSTAT);
  1665. +       if (n & EPT_RX(0))
  1666. +           handle_setup(ui);
  1667. +
  1668. +       n = readl(USB_ENDPTCOMPLETE);
  1669. +       writel(n, USB_ENDPTCOMPLETE);
  1670. +       while (n) {
  1671. +           unsigned bit = __ffs(n);
  1672. +           handle_endpoint(ui, bit);
  1673. +           n = n & (~(1 << bit));
  1674. +       }
  1675. +   }
  1676. +   return IRQ_HANDLED;
  1677. +}
  1678. +
  1679. +static void usb_prepare(struct usb_info *ui)
  1680. +{
  1681. +   spin_lock_init(&ui->lock);
  1682. +
  1683. +   memset(ui->buf, 0, 4096);
  1684. +   ui->head = (void *) (ui->buf + 0);
  1685. +
  1686. +   /* only important for reset/reinit */
  1687. +   memset(ui->ept, 0, sizeof(ui->ept));
  1688. +   ui->next_item = 0;
  1689. +   ui->next_ifc_num = 0;
  1690. +
  1691. +   init_endpoints(ui);
  1692. +
  1693. +   ui->ep0in.ep.maxpacket = 64;
  1694. +   ui->ep0out.ep.maxpacket = 64;
  1695. +
  1696. +   ui->setup_req =
  1697. +       usb_ept_alloc_req(&ui->ep0in, SETUP_BUF_SIZE, GFP_KERNEL);
  1698. +
  1699. +   INIT_WORK(&ui->work, usb_do_work);
  1700. +}
  1701. +
  1702. +static void usb_suspend_phy(struct usb_info *ui)
  1703. +{
  1704. +   /* clear VBusValid and SessionEnd rising interrupts */
  1705. +   ulpi_write(ui, (1 << 1) | (1 << 3), 0x0f);
  1706. +   /* clear VBusValid and SessionEnd falling interrupts */
  1707. +   ulpi_write(ui, (1 << 1) | (1 << 3), 0x12);
  1708. +   /* disable interface protect circuit to drop current consumption */
  1709. +   ulpi_write(ui, (1 << 7), 0x08);
  1710. +}
  1711. +
  1712. +static void usb_reset(struct usb_info *ui)
  1713. +{
  1714. +   unsigned long flags;
  1715. +   unsigned otgsc;
  1716. +
  1717. +   INFO("msm72k_udc: reset controller\n");
  1718. +
  1719. +   spin_lock_irqsave(&ui->lock, flags);
  1720. +   ui->running = 0;
  1721. +   spin_unlock_irqrestore(&ui->lock, flags);
  1722. +
  1723. +#if 0
  1724. +   /* we should flush and shutdown cleanly if already running */
  1725. +   writel(0xffffffff, USB_ENDPTFLUSH);
  1726. +   msleep(2);
  1727. +#endif
  1728. +
  1729. +   otgsc = readl(USB_OTGSC);
  1730. +
  1731. +   /* RESET */
  1732. +   writel(2, USB_USBCMD);
  1733. +   msleep(10);
  1734. +
  1735. +   if (ui->phy_reset)
  1736. +       ui->phy_reset();
  1737. +
  1738. +   /* INCR4 BURST mode */
  1739. +   writel(0x01, USB_SBUSCFG);
  1740. +
  1741. +   /* select DEVICE mode */
  1742. +   writel(0x12, USB_USBMODE);
  1743. +   msleep(1);
  1744. +
  1745. +   /* select ULPI phy */
  1746. +   writel(0x80000000, USB_PORTSC);
  1747. +
  1748. +   ulpi_init(ui);
  1749. +
  1750. +   writel(ui->dma, USB_ENDPOINTLISTADDR);
  1751. +
  1752. +   configure_endpoints(ui);
  1753. +
  1754. +   /* marking us offline will cause ept queue attempts to fail */
  1755. +   ui->online = 0;
  1756. +
  1757. +   /* terminate any pending transactions */
  1758. +   flush_all_endpoints(ui);
  1759. +
  1760. +   if (ui->driver) {
  1761. +       printk(KERN_INFO "usb: notify offline\n");
  1762. +       ui->driver->disconnect(&ui->gadget);
  1763. +   }
  1764. +
  1765. +   /* enable interrupts */
  1766. +   writel(otgsc, USB_OTGSC);
  1767. +   writel(STS_URI | STS_SLI | STS_UI | STS_PCI, USB_USBINTR);
  1768. +
  1769. +   /* go to RUN mode (D+ pullup enable) */
  1770. +   msm72k_pullup(&ui->gadget, 1);
  1771. +
  1772. +   spin_lock_irqsave(&ui->lock, flags);
  1773. +   ui->running = 1;
  1774. +   spin_unlock_irqrestore(&ui->lock, flags);
  1775. +}
  1776. +
  1777. +static void usb_start(struct usb_info *ui)
  1778. +{
  1779. +   unsigned long flags;
  1780. +
  1781. +   spin_lock_irqsave(&ui->lock, flags);
  1782. +   ui->flags |= USB_FLAG_START;
  1783. +   schedule_work(&ui->work);
  1784. +   spin_unlock_irqrestore(&ui->lock, flags);
  1785. +}
  1786. +
  1787. +static struct usb_info *the_usb_info;
  1788. +
  1789. +static int usb_free(struct usb_info *ui, int ret)
  1790. +{
  1791. +   INFO("usb_free(%d)\n", ret);
  1792. +
  1793. +   if (ui->irq)
  1794. +       free_irq(ui->irq, 0);
  1795. +   if (ui->pool)
  1796. +       dma_pool_destroy(ui->pool);
  1797. +   if (ui->dma)
  1798. +       dma_free_coherent(&ui->pdev->dev, 4096, ui->buf, ui->dma);
  1799. +   if (ui->addr)
  1800. +       iounmap(ui->addr);
  1801. +   if (ui->clk)
  1802. +       clk_put(ui->clk);
  1803. +   if (ui->pclk)
  1804. +       clk_put(ui->pclk);
  1805. +   kfree(ui);
  1806. +   return ret;
  1807. +}
  1808. +
  1809. +static void usb_do_work_check_vbus(struct usb_info *ui)
  1810. +{
  1811. +   unsigned long iflags;
  1812. +
  1813. +   spin_lock_irqsave(&ui->lock, iflags);
  1814. +   if (vbus)
  1815. +       ui->flags |= USB_FLAG_VBUS_ONLINE;
  1816. +   else
  1817. +       ui->flags |= USB_FLAG_VBUS_OFFLINE;
  1818. +   spin_unlock_irqrestore(&ui->lock, iflags);
  1819. +}
  1820. +
  1821. +static void usb_do_work(struct work_struct *w)
  1822. +{
  1823. +   struct usb_info *ui = container_of(w, struct usb_info, work);
  1824. +   unsigned long iflags;
  1825. +   unsigned flags, _vbus;
  1826. +
  1827. +   for (;;) {
  1828. +       spin_lock_irqsave(&ui->lock, iflags);
  1829. +       flags = ui->flags;
  1830. +       ui->flags = 0;
  1831. +       _vbus = vbus;
  1832. +       spin_unlock_irqrestore(&ui->lock, iflags);
  1833. +
  1834. +       /* give up if we have nothing to do */
  1835. +       if (flags == 0)
  1836. +           break;
  1837. +
  1838. +       switch (ui->state) {
  1839. +       case USB_STATE_IDLE:
  1840. +           if (flags & USB_FLAG_START) {
  1841. +               pr_info("msm72k_udc: IDLE -> ONLINE\n");
  1842. +               clk_enable(ui->clk);
  1843. +               clk_enable(ui->pclk);
  1844. +               usb_reset(ui);
  1845. +
  1846. +               ui->state = USB_STATE_ONLINE;
  1847. +               usb_do_work_check_vbus(ui);
  1848. +           }
  1849. +           break;
  1850. +       case USB_STATE_ONLINE:
  1851. +           /* If at any point when we were online, we received
  1852. +            * the signal to go offline, we must honor it
  1853. +            */
  1854. +           if (flags & USB_FLAG_VBUS_OFFLINE) {
  1855. +               pr_info("msm72k_udc: ONLINE -> OFFLINE\n");
  1856. +
  1857. +               /* synchronize with irq context */
  1858. +               spin_lock_irqsave(&ui->lock, iflags);
  1859. +               ui->running = 0;
  1860. +               ui->online = 0;
  1861. +               msm72k_pullup(&ui->gadget, 0);
  1862. +               spin_unlock_irqrestore(&ui->lock, iflags);
  1863. +
  1864. +               if (ui->usb_connected)
  1865. +                   ui->usb_connected(0);
  1866. +
  1867. +               /* terminate any transactions, etc */
  1868. +               flush_all_endpoints(ui);
  1869. +
  1870. +               if (ui->driver) {
  1871. +                   printk(KERN_INFO "usb: notify offline\n");
  1872. +                   ui->driver->disconnect(&ui->gadget);
  1873. +               }
  1874. +
  1875. +               /* power down phy, clock down usb */
  1876. +               spin_lock_irqsave(&ui->lock, iflags);
  1877. +               usb_suspend_phy(ui);
  1878. +               clk_disable(ui->pclk);
  1879. +               clk_disable(ui->clk);
  1880. +               spin_unlock_irqrestore(&ui->lock, iflags);
  1881. +
  1882. +               ui->state = USB_STATE_OFFLINE;
  1883. +               usb_do_work_check_vbus(ui);
  1884. +               break;
  1885. +           }
  1886. +           if (flags & USB_FLAG_RESET) {
  1887. +               pr_info("msm72k_udc: ONLINE -> RESET\n");
  1888. +               usb_reset(ui);
  1889. +               pr_info("msm72k_udc: RESET -> ONLINE\n");
  1890. +               break;
  1891. +           }
  1892. +           break;
  1893. +       case USB_STATE_OFFLINE:
  1894. +           /* If we were signaled to go online and vbus is still
  1895. +            * present when we received the signal, go online.
  1896. +            */
  1897. +           if ((flags & USB_FLAG_VBUS_ONLINE) && _vbus) {
  1898. +               pr_info("msm72k_udc: OFFLINE -> ONLINE\n");
  1899. +               clk_enable(ui->clk);
  1900. +               clk_enable(ui->pclk);
  1901. +               usb_reset(ui);
  1902. +
  1903. +               if (ui->usb_connected)
  1904. +                   ui->usb_connected(1);
  1905. +
  1906. +               ui->state = USB_STATE_ONLINE;
  1907. +               usb_do_work_check_vbus(ui);
  1908. +           }
  1909. +           break;
  1910. +       }
  1911. +   }
  1912. +}
  1913. +
  1914. +/* FIXME - the callers of this function should use a gadget API instead.
  1915. + * This is called from htc_battery.c and board-halibut.c
  1916. + * WARNING - this can get called before this driver is initialized.
  1917. + */
  1918. +#if !defined(MODULE)
  1919. +void msm_hsusb_set_vbus_state(int online)
  1920. +#else
  1921. +static void msm_hsusb_set_vbus_state_new(int online)
  1922. +#endif
  1923. +{
  1924. +   unsigned long flags;
  1925. +   struct usb_info *ui = the_usb_info;
  1926. +
  1927. +   if (ui) {
  1928. +       spin_lock_irqsave(&ui->lock, flags);
  1929. +       if (vbus != online) {
  1930. +           vbus = online;
  1931. +           if (online)
  1932. +               ui->flags |= USB_FLAG_VBUS_ONLINE;
  1933. +           else
  1934. +               ui->flags |= USB_FLAG_VBUS_OFFLINE;
  1935. +           schedule_work(&ui->work);
  1936. +       }
  1937. +       spin_unlock_irqrestore(&ui->lock, flags);
  1938. +   } else {
  1939. +       printk(KERN_ERR "msm_hsusb_set_vbus_state called before driver initialized\n");
  1940. +       vbus = online;
  1941. +   }
  1942. +}
  1943. +
  1944. +
  1945. +#if defined(CONFIG_DEBUG_FS)
  1946. +
  1947. +void usb_function_reenumerate(void)
  1948. +{
  1949. +   struct usb_info *ui = the_usb_info;
  1950. +
  1951. +   /* disable and re-enable the D+ pullup */
  1952. +   INFO("msm72k_udc: disable pullup\n");
  1953. +   writel(0x00080000, USB_USBCMD);
  1954. +
  1955. +   msleep(10);
  1956. +
  1957. +   INFO("msm72k_udc: enable pullup\n");
  1958. +   writel(0x00080001, USB_USBCMD);
  1959. +}
  1960. +
  1961. +static char debug_buffer[PAGE_SIZE];
  1962. +
  1963. +static ssize_t debug_read_status(struct file *file, char __user *ubuf,
  1964. +                size_t count, loff_t *ppos)
  1965. +{
  1966. +   struct usb_info *ui = file->private_data;
  1967. +   char *buf = debug_buffer;
  1968. +   unsigned long flags;
  1969. +   struct msm_endpoint *ept;
  1970. +   struct msm_request *req;
  1971. +   int n;
  1972. +   int i = 0;
  1973. +
  1974. +   spin_lock_irqsave(&ui->lock, flags);
  1975. +
  1976. +   i += scnprintf(buf + i, PAGE_SIZE - i,
  1977. +          "regs: setup=%08x prime=%08x stat=%08x done=%08x\n",
  1978. +          readl(USB_ENDPTSETUPSTAT),
  1979. +          readl(USB_ENDPTPRIME),
  1980. +          readl(USB_ENDPTSTAT),
  1981. +          readl(USB_ENDPTCOMPLETE));
  1982. +   i += scnprintf(buf + i, PAGE_SIZE - i,
  1983. +          "regs:   cmd=%08x   sts=%08x intr=%08x port=%08x\n\n",
  1984. +          readl(USB_USBCMD),
  1985. +          readl(USB_USBSTS),
  1986. +          readl(USB_USBINTR),
  1987. +          readl(USB_PORTSC));
  1988. +
  1989. +
  1990. +   for (n = 0; n < 32; n++) {
  1991. +       ept = ui->ept + n;
  1992. +       if (ept->ep.maxpacket == 0)
  1993. +           continue;
  1994. +
  1995. +       i += scnprintf(buf + i, PAGE_SIZE - i,
  1996. +           "ept%d %s cfg=%08x active=%08x next=%08x info=%08x\n",
  1997. +           ept->num, (ept->flags & EPT_FLAG_IN) ? "in " : "out",
  1998. +           ept->head->config, ept->head->active,
  1999. +           ept->head->next, ept->head->info);
  2000. +
  2001. +       for (req = ept->req; req; req = req->next)
  2002. +           i += scnprintf(buf + i, PAGE_SIZE - i,
  2003. +           "  req @%08x next=%08x info=%08x page0=%08x %c %c\n",
  2004. +               req->item_dma, req->item->next,
  2005. +               req->item->info, req->item->page0,
  2006. +               req->busy ? 'B' : ' ',
  2007. +               req->live ? 'L' : ' ');
  2008. +   }
  2009. +
  2010. +   i += scnprintf(buf + i, PAGE_SIZE - i,
  2011. +              "phy failure count: %d\n", ui->phy_fail_count);
  2012. +
  2013. +   spin_unlock_irqrestore(&ui->lock, flags);
  2014. +
  2015. +   return simple_read_from_buffer(ubuf, count, ppos, buf, i);
  2016. +}
  2017. +
  2018. +static ssize_t debug_write_reset(struct file *file, const char __user *buf,
  2019. +                size_t count, loff_t *ppos)
  2020. +{
  2021. +   struct usb_info *ui = file->private_data;
  2022. +   unsigned long flags;
  2023. +
  2024. +   spin_lock_irqsave(&ui->lock, flags);
  2025. +   ui->flags |= USB_FLAG_RESET;
  2026. +   schedule_work(&ui->work);
  2027. +   spin_unlock_irqrestore(&ui->lock, flags);
  2028. +
  2029. +   return count;
  2030. +}
  2031. +
  2032. +static ssize_t debug_write_cycle(struct file *file, const char __user *buf,
  2033. +                size_t count, loff_t *ppos)
  2034. +{
  2035. +   usb_function_reenumerate();
  2036. +   return count;
  2037. +}
  2038. +
  2039. +static int debug_open(struct inode *inode, struct file *file)
  2040. +{
  2041. +   file->private_data = inode->i_private;
  2042. +   return 0;
  2043. +}
  2044. +
  2045. +const struct file_operations debug_stat_ops = {
  2046. +   .open = debug_open,
  2047. +   .read = debug_read_status,
  2048. +};
  2049. +
  2050. +const struct file_operations debug_reset_ops = {
  2051. +   .open = debug_open,
  2052. +   .write = debug_write_reset,
  2053. +};
  2054. +
  2055. +const struct file_operations debug_cycle_ops = {
  2056. +   .open = debug_open,
  2057. +   .write = debug_write_cycle,
  2058. +};
  2059. +
  2060. +static void usb_debugfs_init(struct usb_info *ui)
  2061. +{
  2062. +   struct dentry *dent;
  2063. +   dent = debugfs_create_dir("usb", 0);
  2064. +   if (IS_ERR(dent))
  2065. +       return;
  2066. +
  2067. +   debugfs_create_file("status", 0444, dent, ui, &debug_stat_ops);
  2068. +   debugfs_create_file("reset", 0222, dent, ui, &debug_reset_ops);
  2069. +   debugfs_create_file("cycle", 0222, dent, ui, &debug_cycle_ops);
  2070. +}
  2071. +#else
  2072. +static void usb_debugfs_init(struct usb_info *ui) {}
  2073. +#endif
  2074. +
  2075. +static int
  2076. +msm72k_enable(struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc)
  2077. +{
  2078. +   struct msm_endpoint *ept = to_msm_endpoint(_ep);
  2079. +   unsigned char ep_type =
  2080. +           desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
  2081. +
  2082. +   _ep->maxpacket = le16_to_cpu(desc->wMaxPacketSize);
  2083. +   config_ept(ept);
  2084. +   usb_ept_enable(ept, 1, ep_type);
  2085. +   return 0;
  2086. +}
  2087. +
  2088. +static int msm72k_disable(struct usb_ep *_ep)
  2089. +{
  2090. +   struct msm_endpoint *ept = to_msm_endpoint(_ep);
  2091. +
  2092. +   usb_ept_enable(ept, 0, 0);
  2093. +   return 0;
  2094. +}
  2095. +
  2096. +static struct usb_request *
  2097. +msm72k_alloc_request(struct usb_ep *_ep, gfp_t gfp_flags)
  2098. +{
  2099. +   return usb_ept_alloc_req(to_msm_endpoint(_ep), 0, gfp_flags);
  2100. +}
  2101. +
  2102. +static void
  2103. +msm72k_free_request(struct usb_ep *_ep, struct usb_request *_req)
  2104. +{
  2105. +   struct msm_request *req = to_msm_request(_req);
  2106. +   struct msm_endpoint *ept = to_msm_endpoint(_ep);
  2107. +   struct usb_info *ui = ept->ui;
  2108. +   unsigned long flags;
  2109. +   int dead = 0;
  2110. +
  2111. +   spin_lock_irqsave(&ui->lock, flags);
  2112. +   /* defer freeing resources if request is still busy */
  2113. +   if (req->busy)
  2114. +       dead = req->dead = 1;
  2115. +   spin_unlock_irqrestore(&ui->lock, flags);
  2116. +
  2117. +   /* if req->dead, then we will clean up when the request finishes */
  2118. +   if (!dead)
  2119. +       do_free_req(ui, req);
  2120. +}
  2121. +
  2122. +static int
  2123. +msm72k_queue(struct usb_ep *_ep, struct usb_request *req, gfp_t gfp_flags)
  2124. +{
  2125. +   struct msm_endpoint *ep = to_msm_endpoint(_ep);
  2126. +   struct usb_info *ui = ep->ui;
  2127. +
  2128. +   if (ep == &ui->ep0in) {
  2129. +       struct msm_request *r = to_msm_request(req);
  2130. +       if (!req->length)
  2131. +           goto ep_queue_done;
  2132. +       r->gadget_complete = req->complete;
  2133. +       /* ep0_queue_ack_complete queue a receive for ACK before
  2134. +       ** calling req->complete
  2135. +       */
  2136. +       req->complete = ep0_queue_ack_complete;
  2137. +       if (ui->ep0_dir == USB_DIR_OUT)
  2138. +           ep = &ui->ep0out;
  2139. +   }
  2140. +ep_queue_done:
  2141. +   return usb_ept_queue_xfer(ep, req);
  2142. +}
  2143. +
  2144. +static int msm72k_dequeue(struct usb_ep *_ep, struct usb_request *_req)
  2145. +{
  2146. +   struct msm_endpoint *ep = to_msm_endpoint(_ep);
  2147. +   struct msm_request *req = to_msm_request(_req);
  2148. +   struct usb_info *ui = ep->ui;
  2149. +
  2150. +   struct msm_request *cur, *prev;
  2151. +   unsigned long flags;
  2152. +
  2153. +   if (!_ep || !_req)
  2154. +       return -EINVAL;
  2155. +
  2156. +   spin_lock_irqsave(&ui->lock, flags);
  2157. +   cur = ep->req;
  2158. +   prev = NULL;
  2159. +
  2160. +   while (cur != 0) {
  2161. +       if (cur == req) {
  2162. +           req->busy = 0;
  2163. +           req->live = 0;
  2164. +           req->req.status = -ECONNRESET;
  2165. +           req->req.actual = 0;
  2166. +           if (req->req.complete) {
  2167. +               spin_unlock_irqrestore(&ui->lock, flags);
  2168. +               req->req.complete(&ep->ep, &req->req);
  2169. +               spin_lock_irqsave(&ui->lock, flags);
  2170. +           }
  2171. +           if (req->dead)
  2172. +               do_free_req(ui, req);
  2173. +           /* remove from linked list */
  2174. +           if (prev)
  2175. +               prev->next = cur->next;
  2176. +           else
  2177. +               ep->req = cur->next;
  2178. +           prev = cur;
  2179. +           /* break from loop */
  2180. +           cur = NULL;
  2181. +       } else
  2182. +           cur = cur->next;
  2183. +   }
  2184. +   spin_unlock_irqrestore(&ui->lock, flags);
  2185. +
  2186. +   return 0;
  2187. +}
  2188. +
  2189. +static int
  2190. +msm72k_set_halt(struct usb_ep *_ep, int value)
  2191. +{
  2192. +   struct msm_endpoint *ept = to_msm_endpoint(_ep);
  2193. +   struct usb_info *ui = ept->ui;
  2194. +   unsigned int in = ept->flags & EPT_FLAG_IN;
  2195. +   unsigned int n;
  2196. +   unsigned long flags;
  2197. +
  2198. +   spin_lock_irqsave(&ui->lock, flags);
  2199. +   n = readl(USB_ENDPTCTRL(ept->num));
  2200. +
  2201. +   if (in) {
  2202. +       if (value)
  2203. +           n |= CTRL_TXS;
  2204. +       else {
  2205. +           n &= ~CTRL_TXS;
  2206. +           n |= CTRL_TXR;
  2207. +       }
  2208. +   } else {
  2209. +       if (value)
  2210. +           n |= CTRL_RXS;
  2211. +       else {
  2212. +           n &= ~CTRL_RXS;
  2213. +           n |= CTRL_RXR;
  2214. +       }
  2215. +   }
  2216. +   writel(n, USB_ENDPTCTRL(ept->num));
  2217. +   spin_unlock_irqrestore(&ui->lock, flags);
  2218. +
  2219. +   return 0;
  2220. +}
  2221. +
  2222. +static int
  2223. +msm72k_fifo_status(struct usb_ep *_ep)
  2224. +{
  2225. +   return -EOPNOTSUPP;
  2226. +}
  2227. +
  2228. +static void
  2229. +msm72k_fifo_flush(struct usb_ep *_ep)
  2230. +{
  2231. +   flush_endpoint(to_msm_endpoint(_ep));
  2232. +}
  2233. +
  2234. +static const struct usb_ep_ops msm72k_ep_ops = {
  2235. +   .enable     = msm72k_enable,
  2236. +   .disable    = msm72k_disable,
  2237. +
  2238. +   .alloc_request  = msm72k_alloc_request,
  2239. +   .free_request   = msm72k_free_request,
  2240. +
  2241. +   .queue      = msm72k_queue,
  2242. +   .dequeue    = msm72k_dequeue,
  2243. +
  2244. +   .set_halt   = msm72k_set_halt,
  2245. +   .fifo_status    = msm72k_fifo_status,
  2246. +   .fifo_flush = msm72k_fifo_flush,
  2247. +};
  2248. +
  2249. +static int msm72k_get_frame(struct usb_gadget *_gadget)
  2250. +{
  2251. +   struct usb_info *ui = container_of(_gadget, struct usb_info, gadget);
  2252. +
  2253. +   /* frame number is in bits 13:3 */
  2254. +   return (readl(USB_FRINDEX) >> 3) & 0x000007FF;
  2255. +}
  2256. +
  2257. +/* VBUS reporting logically comes from a transceiver */
  2258. +static int msm72k_udc_vbus_session(struct usb_gadget *_gadget, int is_active)
  2259. +{
  2260. +   msm_hsusb_set_vbus_state(is_active);
  2261. +   return 0;
  2262. +}
  2263. +
  2264. +/* drivers may have software control over D+ pullup */
  2265. +static int msm72k_pullup(struct usb_gadget *_gadget, int is_active)
  2266. +{
  2267. +   struct usb_info *ui = container_of(_gadget, struct usb_info, gadget);
  2268. +
  2269. +   if (is_active) {
  2270. +       if (vbus && ui->driver)
  2271. +           writel(0x00080001, USB_USBCMD);
  2272. +   } else
  2273. +       writel(0x00080000, USB_USBCMD);
  2274. +
  2275. +   return 0;
  2276. +}
  2277. +
  2278. +static int msm72k_wakeup(struct usb_gadget *_gadget)
  2279. +{
  2280. +   struct usb_info *ui = container_of(_gadget, struct usb_info, gadget);
  2281. +   unsigned long flags;
  2282. +
  2283. +   if (!ui->remote_wakeup) {
  2284. +       pr_err("%s: remote wakeup not supported\n", __func__);
  2285. +       return -ENOTSUPP;
  2286. +   }
  2287. +
  2288. +   if (!ui->online) {
  2289. +       pr_err("%s: device is not configured\n", __func__);
  2290. +       return -ENODEV;
  2291. +   }
  2292. +
  2293. +   spin_lock_irqsave(&ui->lock, flags);
  2294. +   if ((readl(USB_PORTSC) & PORTSC_SUSP) == PORTSC_SUSP) {
  2295. +       pr_info("%s: enabling force resume\n", __func__);
  2296. +       writel(readl(USB_PORTSC) | PORTSC_FPR, USB_PORTSC);
  2297. +   }
  2298. +   spin_unlock_irqrestore(&ui->lock, flags);
  2299. +
  2300. +   return 0;
  2301. +}
  2302. +
  2303. +static const struct usb_gadget_ops msm72k_ops = {
  2304. +   .get_frame  = msm72k_get_frame,
  2305. +   .vbus_session   = msm72k_udc_vbus_session,
  2306. +   .pullup     = msm72k_pullup,
  2307. +   .wakeup     = msm72k_wakeup,
  2308. +};
  2309. +
  2310. +static ssize_t usb_remote_wakeup(struct device *dev,
  2311. +       struct device_attribute *attr, const char *buf, size_t count)
  2312. +{
  2313. +   struct usb_info *ui = the_usb_info;
  2314. +
  2315. +   msm72k_wakeup(&ui->gadget);
  2316. +
  2317. +   return count;
  2318. +}
  2319. +static DEVICE_ATTR(wakeup, S_IWUSR, 0, usb_remote_wakeup);
  2320. +
  2321. +static int msm72k_probe(struct platform_device *pdev)
  2322. +{
  2323. +   struct resource *res;
  2324. +   struct usb_info *ui;
  2325. +   int irq;
  2326. +   int ret;
  2327. +
  2328. +   INFO("msm72k_probe\n");
  2329. +   ui = kzalloc(sizeof(struct usb_info), GFP_KERNEL);
  2330. +   if (!ui)
  2331. +       return -ENOMEM;
  2332. +
  2333. +   ui->pdev = pdev;
  2334. +
  2335. +   if (pdev->dev.platform_data) {
  2336. +       struct msm_hsusb_platform_data *pdata = pdev->dev.platform_data;
  2337. +       ui->phy_reset = pdata->phy_reset;
  2338. +       ui->phy_init_seq = pdata->phy_init_seq;
  2339. +       ui->usb_connected = pdata->usb_connected;
  2340. +   }
  2341. +
  2342. +   irq = platform_get_irq(pdev, 0);
  2343. +   res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  2344. +   if (!res || (irq < 0))
  2345. +       return usb_free(ui, -ENODEV);
  2346. +
  2347. +   ui->addr = ioremap(res->start, 4096);
  2348. +   if (!ui->addr)
  2349. +       return usb_free(ui, -ENOMEM);
  2350. +
  2351. +   ui->buf = dma_alloc_coherent(&pdev->dev, 4096, &ui->dma, GFP_KERNEL);
  2352. +   if (!ui->buf)
  2353. +       return usb_free(ui, -ENOMEM);
  2354. +
  2355. +   ui->pool = dma_pool_create("msm72k_udc", NULL, 32, 32, 0);
  2356. +   if (!ui->pool)
  2357. +       return usb_free(ui, -ENOMEM);
  2358. +
  2359. +   INFO("msm72k_probe() io=%p, irq=%d, dma=%p(%x)\n",
  2360. +          ui->addr, irq, ui->buf, ui->dma);
  2361. +
  2362. +   ui->clk = clk_get(&pdev->dev, "usb_hs_clk");
  2363. +   if (IS_ERR(ui->clk))
  2364. +       return usb_free(ui, PTR_ERR(ui->clk));
  2365. +
  2366. +   ui->pclk = clk_get(&pdev->dev, "usb_hs_pclk");
  2367. +   if (IS_ERR(ui->pclk))
  2368. +       return usb_free(ui, PTR_ERR(ui->pclk));
  2369. +
  2370. +   ret = request_irq(irq, usb_interrupt, 0, pdev->name, ui);
  2371. +   if (ret)
  2372. +       return usb_free(ui, ret);
  2373. +   enable_irq_wake(irq);
  2374. +   ui->irq = irq;
  2375. +
  2376. +   ui->gadget.ops = &msm72k_ops;
  2377. +   ui->gadget.is_dualspeed = 1;
  2378. +   device_initialize(&ui->gadget.dev);
  2379. +   ui->gadget.dev.init_name="gadget";
  2380. +   ui->gadget.dev.parent = &pdev->dev;
  2381. +   ui->gadget.dev.dma_mask = pdev->dev.dma_mask;
  2382. +
  2383. +   the_usb_info = ui;
  2384. +
  2385. +   usb_debugfs_init(ui);
  2386. +
  2387. +   usb_prepare(ui);
  2388. +
  2389. +   return 0;
  2390. +}
  2391. +
  2392. +int usb_gadget_register_driver(struct usb_gadget_driver *driver)
  2393. +{
  2394. +   struct usb_info *ui = the_usb_info;
  2395. +   int         retval, n;
  2396. +
  2397. +   if (!driver
  2398. +           || driver->speed < USB_SPEED_FULL
  2399. +           || !driver->bind
  2400. +           || !driver->disconnect
  2401. +           || !driver->setup)
  2402. +       return -EINVAL;
  2403. +   if (!ui)
  2404. +       return -ENODEV;
  2405. +   if (ui->driver)
  2406. +       return -EBUSY;
  2407. +
  2408. +   /* first hook up the driver ... */
  2409. +   ui->driver = driver;
  2410. +   ui->gadget.dev.driver = &driver->driver;
  2411. +   ui->gadget.name = driver_name;
  2412. +   INIT_LIST_HEAD(&ui->gadget.ep_list);
  2413. +   ui->gadget.ep0 = &ui->ep0in.ep;
  2414. +   INIT_LIST_HEAD(&ui->gadget.ep0->ep_list);
  2415. +   ui->gadget.speed = USB_SPEED_UNKNOWN;
  2416. +
  2417. +   for (n = 1; n < 16; n++) {
  2418. +       struct msm_endpoint *ept = ui->ept + n;
  2419. +       list_add_tail(&ept->ep.ep_list, &ui->gadget.ep_list);
  2420. +       ept->ep.maxpacket = 512;
  2421. +   }
  2422. +   for (n = 17; n < 32; n++) {
  2423. +       struct msm_endpoint *ept = ui->ept + n;
  2424. +       list_add_tail(&ept->ep.ep_list, &ui->gadget.ep_list);
  2425. +       ept->ep.maxpacket = 512;
  2426. +   }
  2427. +
  2428. +   retval = device_add(&ui->gadget.dev);
  2429. +   if (retval)
  2430. +       goto fail;
  2431. +
  2432. +   retval = driver->bind(&ui->gadget);
  2433. +   if (retval) {
  2434. +       INFO("bind to driver %s --> error %d\n",
  2435. +               driver->driver.name, retval);
  2436. +       device_del(&ui->gadget.dev);
  2437. +       goto fail;
  2438. +   }
  2439. +
  2440. +   /* create sysfs node for remote wakeup */
  2441. +   retval = device_create_file(&ui->gadget.dev, &dev_attr_wakeup);
  2442. +   if (retval != 0)
  2443. +       INFO("failed to create sysfs entry: (wakeup) error: (%d)\n",
  2444. +                   retval);
  2445. +   INFO("msm72k_udc: registered gadget driver '%s'\n",
  2446. +           driver->driver.name);
  2447. +   usb_start(ui);
  2448. +
  2449. +   return 0;
  2450. +
  2451. +fail:
  2452. +   ui->driver = NULL;
  2453. +   ui->gadget.dev.driver = NULL;
  2454. +   return retval;
  2455. +}
  2456. +EXPORT_SYMBOL(usb_gadget_register_driver);
  2457. +
  2458. +int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
  2459. +{
  2460. +   struct usb_info *dev = the_usb_info;
  2461. +
  2462. +   if (!dev)
  2463. +       return -ENODEV;
  2464. +   if (!driver || driver != dev->driver || !driver->unbind)
  2465. +       return -EINVAL;
  2466. +
  2467. +   device_remove_file(&dev->gadget.dev, &dev_attr_wakeup);
  2468. +   driver->unbind(&dev->gadget);
  2469. +   dev->gadget.dev.driver = NULL;
  2470. +   dev->driver = NULL;
  2471. +
  2472. +   device_del(&dev->gadget.dev);
  2473. +
  2474. +   VDEBUG("unregistered gadget driver '%s'\n", driver->driver.name);
  2475. +   return 0;
  2476. +}
  2477. +EXPORT_SYMBOL(usb_gadget_unregister_driver);
  2478. +
  2479. +
  2480. +static struct platform_driver usb_driver = {
  2481. +   .probe = msm72k_probe,
  2482. +   .driver = { .name = "msm_hsusb", },
  2483. +};
  2484. +
  2485. +#if defined(MODULE)
  2486. +extern void (*msm_hsusb_set_vbus_state)(int online);
  2487. +#endif
  2488. +
  2489. +static int __init init(void)
  2490. +{
  2491. +   #if defined(MODULE)
  2492. +   msm_hsusb_set_vbus_state = &msm_hsusb_set_vbus_state_new;
  2493. +   #endif
  2494. +   return platform_driver_register(&usb_driver);
  2495. +}
  2496. +module_init(init);
  2497. +
  2498. +static void __exit cleanup(void)
  2499. +{
  2500. +   platform_driver_unregister(&usb_driver);
  2501. +}
  2502. +module_exit(cleanup);
  2503. +
  2504. +MODULE_DESCRIPTION(DRIVER_DESC);
  2505. +MODULE_AUTHOR("Mike Lockwood, Brian Swetland");
  2506. +MODULE_LICENSE("GPL");
  2507. diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
  2508. index e54a337..430a086 100644
  2509. --- a/drivers/video/backlight/Kconfig
  2510. +++ b/drivers/video/backlight/Kconfig
  2511. @@ -185,6 +185,15 @@ config BACKLIGHT_OMAP1
  2512.       the PWL module of OMAP1 processors.  Say Y if your board
  2513.       uses this hardware.
  2514.  
  2515. +config BACKLIGHT_TROUT
  2516. +   tristate "Backlight driver for the MSM trout board (e.g. htcdream)"
  2517. +   depends on MACH_TROUT
  2518. +   default y
  2519. +   help
  2520. +     This driver controls the LCD backlight level and power for
  2521. +     the PWL module of the armv6 processors.  Say Y if your board
  2522. +     uses this hardware.
  2523. +
  2524.  config BACKLIGHT_HP680
  2525.     tristate "HP Jornada 680 Backlight Driver"
  2526.     depends on SH_HP6XX
  2527. diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
  2528. index 44c0f81..1d962ed 100644
  2529. --- a/drivers/video/backlight/Makefile
  2530. +++ b/drivers/video/backlight/Makefile
  2531. @@ -35,4 +35,5 @@ obj-$(CONFIG_BACKLIGHT_ADP5520)   += adp5520_bl.o
  2532.  obj-$(CONFIG_BACKLIGHT_ADP8860)    += adp8860_bl.o
  2533.  obj-$(CONFIG_BACKLIGHT_88PM860X) += 88pm860x_bl.o
  2534.  obj-$(CONFIG_BACKLIGHT_PCF50633)   += pcf50633-backlight.o
  2535. +obj-$(CONFIG_BACKLIGHT_TROUT)  += trout_bl.o
  2536.  
  2537. diff --git a/drivers/video/backlight/trout_bl.c b/drivers/video/backlight/trout_bl.c
  2538. new file mode 100644
  2539. index 0000000..4539324
  2540. --- /dev/null
  2541. +++ b/drivers/video/backlight/trout_bl.c
  2542. @@ -0,0 +1,661 @@
  2543. +/* linux/arch/arm/mach-msm/board-trout-mddi.c
  2544. +** Author: Brian Swetland <swetland@google.com>
  2545. +*/
  2546. +
  2547. +#include <linux/kernel.h>
  2548. +#include <linux/init.h>
  2549. +#include <linux/platform_device.h>
  2550. +#include <linux/delay.h>
  2551. +#include <linux/backlight.h>
  2552. +#include <linux/clk.h>
  2553. +#include <linux/err.h>
  2554. +#include <linux/gpio.h>
  2555. +
  2556. +#include <asm/io.h>
  2557. +#include <asm/gpio.h>
  2558. +#include <asm/mach-types.h>
  2559. +
  2560. +#include <mach/msm_fb.h>
  2561. +#include <mach/vreg.h>
  2562. +#include <mach/htc_pwrsink.h>
  2563. +
  2564. +#include <../board-trout.h>
  2565. +#include <../proc_comm.h>
  2566. +#include <../devices.h>
  2567. +
  2568. +#define TROUT_DEFAULT_BACKLIGHT_BRIGHTNESS 127
  2569. +
  2570. +static struct clk *gp_clk;
  2571. +static int trout_backlight_off;
  2572. +static int trout_backlight_resume_level = TROUT_DEFAULT_BACKLIGHT_BRIGHTNESS;
  2573. +static int trout_new_backlight = 1;
  2574. +static uint8_t trout_backlight_last_level = 33;
  2575. +static DEFINE_MUTEX(trout_backlight_lock);
  2576. +
  2577. +static void trout_set_backlight_level(uint8_t level)
  2578. +{
  2579. +   unsigned percent = ((int)level * 100) / 255;
  2580. +
  2581. +   if (trout_new_backlight) {
  2582. +       unsigned long flags;
  2583. +       int i = 0;
  2584. +       level = (int)level * 34 / 256;
  2585. +
  2586. +       if (trout_backlight_last_level == level)
  2587. +           return;
  2588. +
  2589. +       if (level == 0) {
  2590. +           gpio_set_value(27, 0);
  2591. +           msleep(2);
  2592. +       } else {
  2593. +           local_irq_save(flags);
  2594. +           if (trout_backlight_last_level == 0) {
  2595. +               gpio_set_value(27, 1);
  2596. +               udelay(40);
  2597. +               trout_backlight_last_level = 33;
  2598. +           }
  2599. +           i = (trout_backlight_last_level - level + 33) % 33;
  2600. +           while (i-- > 0) {
  2601. +               gpio_set_value(27, 0);
  2602. +               udelay(1);
  2603. +               gpio_set_value(27, 1);
  2604. +               udelay(1);
  2605. +           }
  2606. +           local_irq_restore(flags);
  2607. +       }
  2608. +       trout_backlight_last_level = level;
  2609. +   }
  2610. +   else {
  2611. +       if(level) {
  2612. +           clk_enable(gp_clk);
  2613. +           writel((1U << 16) | (~level & 0xffff),
  2614. +                  MSM_CLK_CTL_BASE + 0x58);
  2615. +           /* Going directly to a 100% duty cycle does not
  2616. +            *  seem to work */
  2617. +           if(level == 255) {
  2618. +               writel((~127 << 16) | 0xb20,
  2619. +                      MSM_CLK_CTL_BASE + 0x5c);
  2620. +               udelay(1);
  2621. +           }
  2622. +           writel((~127 << 16) | 0xb58, MSM_CLK_CTL_BASE + 0x5c);
  2623. +       }
  2624. +       else {
  2625. +           writel(0x0, MSM_CLK_CTL_BASE + 0x5c);
  2626. +           clk_disable(gp_clk);
  2627. +       }
  2628. +   }
  2629. +   htc_pwrsink_set(PWRSINK_BACKLIGHT, percent);
  2630. +}
  2631. +
  2632. +#define MDDI_CLIENT_CORE_BASE  0x108000
  2633. +#define LCD_CONTROL_BLOCK_BASE 0x110000
  2634. +#define SPI_BLOCK_BASE         0x120000
  2635. +#define I2C_BLOCK_BASE         0x130000
  2636. +#define PWM_BLOCK_BASE         0x140000
  2637. +#define GPIO_BLOCK_BASE        0x150000
  2638. +#define SYSTEM_BLOCK1_BASE     0x160000
  2639. +#define SYSTEM_BLOCK2_BASE     0x170000
  2640. +
  2641. +
  2642. +#define    DPSUS       (MDDI_CLIENT_CORE_BASE|0x24)
  2643. +#define    SYSCLKENA   (MDDI_CLIENT_CORE_BASE|0x2C)
  2644. +#define    PWM0OFF       (PWM_BLOCK_BASE|0x1C)
  2645. +
  2646. +#define V_VDDE2E_VDD2_GPIO 0
  2647. +#define MDDI_RST_N 82
  2648. +
  2649. +#define    MDDICAP0    (MDDI_CLIENT_CORE_BASE|0x00)
  2650. +#define    MDDICAP1    (MDDI_CLIENT_CORE_BASE|0x04)
  2651. +#define    MDDICAP2    (MDDI_CLIENT_CORE_BASE|0x08)
  2652. +#define    MDDICAP3    (MDDI_CLIENT_CORE_BASE|0x0C)
  2653. +#define    MDCAPCHG    (MDDI_CLIENT_CORE_BASE|0x10)
  2654. +#define    MDCRCERC    (MDDI_CLIENT_CORE_BASE|0x14)
  2655. +#define    TTBUSSEL    (MDDI_CLIENT_CORE_BASE|0x18)
  2656. +#define    DPSET0      (MDDI_CLIENT_CORE_BASE|0x1C)
  2657. +#define    DPSET1      (MDDI_CLIENT_CORE_BASE|0x20)
  2658. +#define    DPSUS       (MDDI_CLIENT_CORE_BASE|0x24)
  2659. +#define    DPRUN       (MDDI_CLIENT_CORE_BASE|0x28)
  2660. +#define    SYSCKENA    (MDDI_CLIENT_CORE_BASE|0x2C)
  2661. +#define    TESTMODE    (MDDI_CLIENT_CORE_BASE|0x30)
  2662. +#define    FIFOMONI    (MDDI_CLIENT_CORE_BASE|0x34)
  2663. +#define    INTMONI     (MDDI_CLIENT_CORE_BASE|0x38)
  2664. +#define    MDIOBIST    (MDDI_CLIENT_CORE_BASE|0x3C)
  2665. +#define    MDIOPSET    (MDDI_CLIENT_CORE_BASE|0x40)
  2666. +#define    BITMAP0     (MDDI_CLIENT_CORE_BASE|0x44)
  2667. +#define    BITMAP1     (MDDI_CLIENT_CORE_BASE|0x48)
  2668. +#define    BITMAP2     (MDDI_CLIENT_CORE_BASE|0x4C)
  2669. +#define    BITMAP3     (MDDI_CLIENT_CORE_BASE|0x50)
  2670. +#define    BITMAP4     (MDDI_CLIENT_CORE_BASE|0x54)
  2671. +
  2672. +#define    SRST        (LCD_CONTROL_BLOCK_BASE|0x00)
  2673. +#define    PORT_ENB    (LCD_CONTROL_BLOCK_BASE|0x04)
  2674. +#define    START       (LCD_CONTROL_BLOCK_BASE|0x08)
  2675. +#define    PORT        (LCD_CONTROL_BLOCK_BASE|0x0C)
  2676. +#define    CMN         (LCD_CONTROL_BLOCK_BASE|0x10)
  2677. +#define    GAMMA       (LCD_CONTROL_BLOCK_BASE|0x14)
  2678. +#define    INTFLG      (LCD_CONTROL_BLOCK_BASE|0x18)
  2679. +#define    INTMSK      (LCD_CONTROL_BLOCK_BASE|0x1C)
  2680. +#define    MPLFBUF     (LCD_CONTROL_BLOCK_BASE|0x20)
  2681. +#define    HDE_LEFT    (LCD_CONTROL_BLOCK_BASE|0x24)
  2682. +#define    VDE_TOP     (LCD_CONTROL_BLOCK_BASE|0x28)
  2683. +#define    PXL         (LCD_CONTROL_BLOCK_BASE|0x30)
  2684. +#define    HCYCLE      (LCD_CONTROL_BLOCK_BASE|0x34)
  2685. +#define    HSW         (LCD_CONTROL_BLOCK_BASE|0x38)
  2686. +#define    HDE_START   (LCD_CONTROL_BLOCK_BASE|0x3C)
  2687. +#define    HDE_SIZE    (LCD_CONTROL_BLOCK_BASE|0x40)
  2688. +#define    VCYCLE      (LCD_CONTROL_BLOCK_BASE|0x44)
  2689. +#define    VSW         (LCD_CONTROL_BLOCK_BASE|0x48)
  2690. +#define    VDE_START   (LCD_CONTROL_BLOCK_BASE|0x4C)
  2691. +#define    VDE_SIZE    (LCD_CONTROL_BLOCK_BASE|0x50)
  2692. +#define    WAKEUP      (LCD_CONTROL_BLOCK_BASE|0x54)
  2693. +#define    WSYN_DLY    (LCD_CONTROL_BLOCK_BASE|0x58)
  2694. +#define    REGENB      (LCD_CONTROL_BLOCK_BASE|0x5C)
  2695. +#define    VSYNIF      (LCD_CONTROL_BLOCK_BASE|0x60)
  2696. +#define    WRSTB       (LCD_CONTROL_BLOCK_BASE|0x64)
  2697. +#define    RDSTB       (LCD_CONTROL_BLOCK_BASE|0x68)
  2698. +#define    ASY_DATA    (LCD_CONTROL_BLOCK_BASE|0x6C)
  2699. +#define    ASY_DATB    (LCD_CONTROL_BLOCK_BASE|0x70)
  2700. +#define    ASY_DATC    (LCD_CONTROL_BLOCK_BASE|0x74)
  2701. +#define    ASY_DATD    (LCD_CONTROL_BLOCK_BASE|0x78)
  2702. +#define    ASY_DATE    (LCD_CONTROL_BLOCK_BASE|0x7C)
  2703. +#define    ASY_DATF    (LCD_CONTROL_BLOCK_BASE|0x80)
  2704. +#define    ASY_DATG    (LCD_CONTROL_BLOCK_BASE|0x84)
  2705. +#define    ASY_DATH    (LCD_CONTROL_BLOCK_BASE|0x88)
  2706. +#define    ASY_CMDSET  (LCD_CONTROL_BLOCK_BASE|0x8C)
  2707. +
  2708. +#define    SSICTL      (SPI_BLOCK_BASE|0x00)
  2709. +#define    SSITIME     (SPI_BLOCK_BASE|0x04)
  2710. +#define    SSITX       (SPI_BLOCK_BASE|0x08)
  2711. +#define    SSIRX       (SPI_BLOCK_BASE|0x0C)
  2712. +#define    SSIINTC     (SPI_BLOCK_BASE|0x10)
  2713. +#define    SSIINTS     (SPI_BLOCK_BASE|0x14)
  2714. +#define    SSIDBG1     (SPI_BLOCK_BASE|0x18)
  2715. +#define    SSIDBG2     (SPI_BLOCK_BASE|0x1C)
  2716. +#define    SSIID       (SPI_BLOCK_BASE|0x20)
  2717. +
  2718. +#define    WKREQ       (SYSTEM_BLOCK1_BASE|0x00)
  2719. +#define    CLKENB      (SYSTEM_BLOCK1_BASE|0x04)
  2720. +#define    DRAMPWR     (SYSTEM_BLOCK1_BASE|0x08)
  2721. +#define    INTMASK     (SYSTEM_BLOCK1_BASE|0x0C)
  2722. +#define    GPIOSEL     (SYSTEM_BLOCK2_BASE|0x00)
  2723. +
  2724. +#define    GPIODATA    (GPIO_BLOCK_BASE|0x00)
  2725. +#define    GPIODIR     (GPIO_BLOCK_BASE|0x04)
  2726. +#define    GPIOIS      (GPIO_BLOCK_BASE|0x08)
  2727. +#define    GPIOIBE     (GPIO_BLOCK_BASE|0x0C)
  2728. +#define    GPIOIEV     (GPIO_BLOCK_BASE|0x10)
  2729. +#define    GPIOIE      (GPIO_BLOCK_BASE|0x14)
  2730. +#define    GPIORIS     (GPIO_BLOCK_BASE|0x18)
  2731. +#define    GPIOMIS     (GPIO_BLOCK_BASE|0x1C)
  2732. +#define    GPIOIC      (GPIO_BLOCK_BASE|0x20)
  2733. +#define    GPIOOMS     (GPIO_BLOCK_BASE|0x24)
  2734. +#define    GPIOPC      (GPIO_BLOCK_BASE|0x28)
  2735. +#define    GPIOID      (GPIO_BLOCK_BASE|0x30)
  2736. +
  2737. +#define SPI_WRITE(reg, val) \
  2738. +   { SSITX,        0x00010000 | (((reg) & 0xff) << 8) | ((val) & 0xff) }, \
  2739. +   { 0, 5 },
  2740. +
  2741. +#define SPI_WRITE1(reg) \
  2742. +   { SSITX,        (reg) & 0xff }, \
  2743. +   { 0, 5 },
  2744. +
  2745. +struct mddi_table {
  2746. +   uint32_t reg;
  2747. +   uint32_t value;
  2748. +};
  2749. +static struct mddi_table mddi_toshiba_init_table[] = {
  2750. +   { DPSET0,       0x09e90046 },
  2751. +   { DPSET1,       0x00000118 },
  2752. +   { DPSUS,        0x00000000 },
  2753. +   { DPRUN,        0x00000001 },
  2754. +   { 1,            14         }, /* msleep 14 */
  2755. +   { SYSCKENA,     0x00000001 },
  2756. +   //{ CLKENB,       0x000000EF },
  2757. +   { CLKENB,       0x0000A1EF },  /*    # SYS.CLKENB  # Enable clocks for each module (without DCLK , i2cCLK) */
  2758. +   //{ CLKENB,       0x000025CB }, /* Clock enable register */
  2759. +
  2760. +   { GPIODATA,     0x02000200 },  /*   # GPI .GPIODATA  # GPIO2(RESET_LCD_N) set to 0 , GPIO3(eDRAM_Power) set to 0 */
  2761. +   { GPIODIR,      0x000030D  },  /* 24D   # GPI .GPIODIR  # Select direction of GPIO port (0,2,3,6,9 output) */
  2762. +   { GPIOSEL,      0/*0x00000173*/},  /*   # SYS.GPIOSEL  # GPIO port multiplexing control */
  2763. +   { GPIOPC,       0x03C300C0 },  /*   # GPI .GPIOPC  # GPIO2,3 PD cut */
  2764. +   { WKREQ,        0x00000000 },  /*   # SYS.WKREQ  # Wake-up request event is VSYNC alignment */
  2765. +
  2766. +   { GPIOIBE,      0x000003FF },
  2767. +   { GPIOIS,       0x00000000 },
  2768. +   { GPIOIC,       0x000003FF },
  2769. +   { GPIOIE,       0x00000000 },
  2770. +
  2771. +   { GPIODATA,     0x00040004 },  /*   # GPI .GPIODATA  # eDRAM VD supply */
  2772. +   { 1,            1          }, /* msleep 1 */
  2773. +   { GPIODATA,     0x02040004 },  /*   # GPI .GPIODATA  # eDRAM VD supply */
  2774. +   { DRAMPWR,      0x00000001 }, /* eDRAM power */
  2775. +};
  2776. +
  2777. +static struct mddi_table mddi_toshiba_panel_init_table[] = {
  2778. +   { SRST,         0x00000003 }, /* FIFO/LCDC not reset */
  2779. +   { PORT_ENB,     0x00000001 }, /* Enable sync. Port */
  2780. +   { START,        0x00000000 }, /* To stop operation */
  2781. +   //{ START,        0x00000001 }, /* To start operation */
  2782. +   { PORT,         0x00000004 }, /* Polarity of VS/HS/DE. */
  2783. +   { CMN,          0x00000000 },
  2784. +   { GAMMA,        0x00000000 }, /* No Gamma correction */
  2785. +   { INTFLG,       0x00000000 }, /* VSYNC interrupt flag clear/status */
  2786. +   { INTMSK,       0x00000000 }, /* VSYNC interrupt mask is off. */
  2787. +   { MPLFBUF,      0x00000000 }, /* Select frame buffer's base address. */
  2788. +   { HDE_LEFT,     0x00000000 }, /* The value of HDE_LEFT. */
  2789. +   { VDE_TOP,      0x00000000 }, /* The value of VDE_TPO. */
  2790. +   { PXL,          0x00000001 }, /* 1. RGB666 */
  2791. +                                 /* 2. Data is valid from 1st frame of beginning. */
  2792. +   { HDE_START,    0x00000006 }, /* HDE_START= 14 PCLK */
  2793. +   { HDE_SIZE,     0x0000009F }, /* HDE_SIZE=320 PCLK */
  2794. +   { HSW,          0x00000004 }, /* HSW= 10 PCLK */
  2795. +   { VSW,          0x00000001 }, /* VSW=2 HCYCLE */
  2796. +   { VDE_START,    0x00000003 }, /* VDE_START=4 HCYCLE */
  2797. +   { VDE_SIZE,     0x000001DF }, /* VDE_SIZE=480 HCYCLE */
  2798. +   { WAKEUP,       0x000001e2 }, /* Wakeup position in VSYNC mode. */
  2799. +   { WSYN_DLY,     0x00000000 }, /* Wakeup position in VSIN mode. */
  2800. +   { REGENB,       0x00000001 }, /* Set 1 to enable to change the value of registers. */
  2801. +   { CLKENB,       0x000025CB }, /* Clock enable register */
  2802. +
  2803. +   { SSICTL,       0x00000170 }, /* SSI control register */
  2804. +   { SSITIME,      0x00000250 }, /* SSI timing control register */
  2805. +   { SSICTL,       0x00000172 }, /* SSI control register */
  2806. +};
  2807. +
  2808. +
  2809. +static struct mddi_table mddi_sharp_init_table[] = {
  2810. +   { VCYCLE,       0x000001eb },
  2811. +   { HCYCLE,       0x000000ae },
  2812. +   { REGENB,       0x00000001 }, /* Set 1 to enable to change the value of registers. */
  2813. +   { GPIODATA,     0x00040000 }, /* GPIO2 low */
  2814. +   { GPIODIR,      0x00000004 }, /* GPIO2 out */
  2815. +   { 1,            1          }, /* msleep 1 */
  2816. +   { GPIODATA,     0x00040004 }, /* GPIO2 high */
  2817. +   { 1,            10         }, /* msleep 10 */
  2818. +   SPI_WRITE(0x5f, 0x01)
  2819. +   SPI_WRITE1(0x11)
  2820. +   { 1,            200        }, /* msleep 200 */
  2821. +   SPI_WRITE1(0x29)
  2822. +   SPI_WRITE1(0xde)
  2823. +   { START,        0x00000001 }, /* To start operation */
  2824. +};
  2825. +
  2826. +static struct mddi_table mddi_sharp_deinit_table[] = {
  2827. +   { 1,            200        }, /* msleep 200 */
  2828. +   SPI_WRITE(0x10, 0x1)
  2829. +   { 1,            100        }, /* msleep 100 */
  2830. +   { GPIODATA,     0x00040004 }, /* GPIO2 high */
  2831. +   { GPIODIR,      0x00000004 }, /* GPIO2 out */
  2832. +   { GPIODATA,     0x00040000 }, /* GPIO2 low */
  2833. +   { 1,            10         }, /* msleep 10 */
  2834. +};
  2835. +
  2836. +static struct mddi_table mddi_tpo_init_table[] = {
  2837. +   { VCYCLE,       0x000001e5 },
  2838. +   { HCYCLE,       0x000000ac },
  2839. +   { REGENB,       0x00000001 }, /* Set 1 to enable to change the value of registers. */
  2840. +   { 0,            20         }, /* udelay 20 */
  2841. +   { GPIODATA,     0x00000004 }, /* GPIO2 high */
  2842. +   { GPIODIR,      0x00000004 }, /* GPIO2 out */
  2843. +   { 0,            20         }, /* udelay 20 */
  2844. +
  2845. +   SPI_WRITE(0x08, 0x01)
  2846. +   { 0,            500        }, /* udelay 500 */
  2847. +   SPI_WRITE(0x08, 0x00)
  2848. +   SPI_WRITE(0x02, 0x00)
  2849. +   SPI_WRITE(0x03, 0x04)
  2850. +   SPI_WRITE(0x04, 0x0e)
  2851. +   SPI_WRITE(0x09, 0x02)
  2852. +   SPI_WRITE(0x0b, 0x08)
  2853. +   SPI_WRITE(0x0c, 0x53)
  2854. +   SPI_WRITE(0x0d, 0x01)
  2855. +   SPI_WRITE(0x0e, 0xe0)
  2856. +   SPI_WRITE(0x0f, 0x01)
  2857. +   SPI_WRITE(0x10, 0x58)
  2858. +   SPI_WRITE(0x20, 0x1e)
  2859. +   SPI_WRITE(0x21, 0x0a)
  2860. +   SPI_WRITE(0x22, 0x0a)
  2861. +   SPI_WRITE(0x23, 0x1e)
  2862. +   SPI_WRITE(0x25, 0x32)
  2863. +   SPI_WRITE(0x26, 0x00)
  2864. +   SPI_WRITE(0x27, 0xac)
  2865. +   SPI_WRITE(0x29, 0x06)
  2866. +   SPI_WRITE(0x2a, 0xa4)
  2867. +   SPI_WRITE(0x2b, 0x45)
  2868. +   SPI_WRITE(0x2c, 0x45)
  2869. +   SPI_WRITE(0x2d, 0x15)
  2870. +   SPI_WRITE(0x2e, 0x5a)
  2871. +   SPI_WRITE(0x2f, 0xff)
  2872. +   SPI_WRITE(0x30, 0x6b)
  2873. +   SPI_WRITE(0x31, 0x0d)
  2874. +   SPI_WRITE(0x32, 0x48)
  2875. +   SPI_WRITE(0x33, 0x82)
  2876. +   SPI_WRITE(0x34, 0xbd)
  2877. +   SPI_WRITE(0x35, 0xe7)
  2878. +   SPI_WRITE(0x36, 0x18)
  2879. +   SPI_WRITE(0x37, 0x94)
  2880. +   SPI_WRITE(0x38, 0x01)
  2881. +   SPI_WRITE(0x39, 0x5d)
  2882. +   SPI_WRITE(0x3a, 0xae)
  2883. +   SPI_WRITE(0x3b, 0xff)
  2884. +   SPI_WRITE(0x07, 0x09)
  2885. +   { 0,            10         }, /* udelay 10 */
  2886. +   { START,        0x00000001 }, /* To start operation */
  2887. +};
  2888. +
  2889. +static struct mddi_table mddi_tpo_deinit_table[] = {
  2890. +   SPI_WRITE(0x07, 0x19)
  2891. +   { START,        0x00000000 }, /* To stop operation */
  2892. +   { GPIODATA,     0x00040004 }, /* GPIO2 high */
  2893. +   { GPIODIR,      0x00000004 }, /* GPIO2 out */
  2894. +   { GPIODATA,     0x00040000 }, /* GPIO2 low */
  2895. +   { 0,            5        }, /* usleep 5 */
  2896. +};
  2897. +
  2898. +
  2899. +#define GPIOSEL_VWAKEINT (1U << 0)
  2900. +#define INTMASK_VWAKEOUT (1U << 0)
  2901. +
  2902. +static void trout_process_mddi_table(struct msm_mddi_client_data *client_data,
  2903. +                    struct mddi_table *table, size_t count)
  2904. +{
  2905. +   int i;
  2906. +   for(i = 0; i < count; i++) {
  2907. +       uint32_t reg = table[i].reg;
  2908. +       uint32_t value = table[i].value;
  2909. +
  2910. +       if (reg == 0)
  2911. +           udelay(value);
  2912. +       else if (reg == 1)
  2913. +           msleep(value);
  2914. +       else
  2915. +           client_data->remote_write(client_data, value, reg);
  2916. +   }
  2917. +}
  2918. +
  2919. +static struct vreg *vreg_mddi_1v5;
  2920. +static struct vreg *vreg_lcm_2v85;
  2921. +
  2922. +static void trout_mddi_power_client(struct msm_mddi_client_data *client_data,
  2923. +                   int on)
  2924. +{
  2925. +    unsigned id, on_off;
  2926. +   if(on) {
  2927. +       on_off = 0;
  2928. +       id = PM_VREG_PDOWN_MDDI_ID;
  2929. +       msm_proc_comm(PCOM_VREG_PULLDOWN, &on_off, &id);
  2930. +       vreg_enable(vreg_mddi_1v5);
  2931. +       mdelay(5); // delay time >5ms and <10ms
  2932. +       gpio_set_value(V_VDDE2E_VDD2_GPIO, 1);
  2933. +       gpio_set_value(TROUT_GPIO_MDDI_32K_EN, 1);
  2934. +       msleep(3);
  2935. +       id = PM_VREG_PDOWN_AUX_ID;
  2936. +       msm_proc_comm(PCOM_VREG_PULLDOWN, &on_off, &id);
  2937. +       vreg_enable(vreg_lcm_2v85);
  2938. +       msleep(3);
  2939. +       gpio_set_value(MDDI_RST_N, 1);
  2940. +       msleep(10);
  2941. +   } else {
  2942. +       gpio_set_value(TROUT_GPIO_MDDI_32K_EN, 0);
  2943. +       gpio_set_value(MDDI_RST_N, 0);
  2944. +       msleep(10);
  2945. +       vreg_disable(vreg_lcm_2v85);
  2946. +       on_off = 1;
  2947. +       id = PM_VREG_PDOWN_AUX_ID;
  2948. +       msm_proc_comm(PCOM_VREG_PULLDOWN, &on_off, &id);
  2949. +       msleep(5);
  2950. +       gpio_set_value(V_VDDE2E_VDD2_GPIO, 0);
  2951. +       msleep(200);
  2952. +       vreg_disable(vreg_mddi_1v5);
  2953. +       id = PM_VREG_PDOWN_MDDI_ID;
  2954. +       msm_proc_comm(PCOM_VREG_PULLDOWN, &on_off, &id);
  2955. +   }
  2956. +}
  2957. +
  2958. +static int trout_mddi_toshiba_client_init(
  2959. +   struct msm_mddi_bridge_platform_data *bridge_data,
  2960. +   struct msm_mddi_client_data *client_data)
  2961. +{
  2962. +   int panel_id;
  2963. +
  2964. +   client_data->auto_hibernate(client_data, 0);
  2965. +   trout_process_mddi_table(client_data, mddi_toshiba_init_table,
  2966. +                ARRAY_SIZE(mddi_toshiba_init_table));
  2967. +   client_data->auto_hibernate(client_data, 1);
  2968. +   panel_id = (client_data->remote_read(client_data, GPIODATA) >> 4) & 3;
  2969. +   if (panel_id > 1) {
  2970. +       printk("unknown panel id at mddi_enable\n");
  2971. +       return -1;
  2972. +   }
  2973. +   return 0;
  2974. +}
  2975. +
  2976. +static int trout_mddi_toshiba_client_uninit(
  2977. +   struct msm_mddi_bridge_platform_data *bridge_data,
  2978. +   struct msm_mddi_client_data *client_data)
  2979. +{
  2980. +   return 0;
  2981. +}
  2982. +
  2983. +static int trout_mddi_panel_unblank(
  2984. +   struct msm_mddi_bridge_platform_data *bridge_data,
  2985. +   struct msm_mddi_client_data *client_data)
  2986. +{
  2987. +
  2988. +   int panel_id, ret = 0;
  2989. +
  2990. +   trout_set_backlight_level(0);
  2991. +   client_data->auto_hibernate(client_data, 0);
  2992. +   trout_process_mddi_table(client_data, mddi_toshiba_panel_init_table,
  2993. +       ARRAY_SIZE(mddi_toshiba_panel_init_table));
  2994. +   panel_id = (client_data->remote_read(client_data, GPIODATA) >> 4) & 3;
  2995. +   switch(panel_id) {
  2996. +    case 0:
  2997. +       printk("init sharp panel\n");
  2998. +       trout_process_mddi_table(client_data,
  2999. +                    mddi_sharp_init_table,
  3000. +                    ARRAY_SIZE(mddi_sharp_init_table));
  3001. +       break;
  3002. +   case 1:
  3003. +       printk("init tpo panel\n");
  3004. +       trout_process_mddi_table(client_data,
  3005. +                    mddi_tpo_init_table,
  3006. +                    ARRAY_SIZE(mddi_tpo_init_table));
  3007. +       break;
  3008. +   default:
  3009. +       printk("unknown panel_id: %d\n", panel_id);
  3010. +       ret = -1;
  3011. +   };
  3012. +   mutex_lock(&trout_backlight_lock);
  3013. +   trout_set_backlight_level(trout_backlight_resume_level);
  3014. +   trout_backlight_off = 0;
  3015. +   mutex_unlock(&trout_backlight_lock);
  3016. +   client_data->auto_hibernate(client_data, 1);
  3017. +   client_data->remote_write(client_data, GPIOSEL_VWAKEINT, GPIOSEL);
  3018. +   client_data->remote_write(client_data, INTMASK_VWAKEOUT, INTMASK);
  3019. +   return ret;
  3020. +
  3021. +}
  3022. +
  3023. +static int trout_mddi_panel_blank(
  3024. +   struct msm_mddi_bridge_platform_data *bridge_data,
  3025. +   struct msm_mddi_client_data *client_data)
  3026. +{
  3027. +   int panel_id, ret = 0;
  3028. +
  3029. +   panel_id = (client_data->remote_read(client_data, GPIODATA) >> 4) & 3;
  3030. +   client_data->auto_hibernate(client_data, 0);
  3031. +   switch(panel_id) {
  3032. +   case 0:
  3033. +       printk("deinit sharp panel\n");
  3034. +       trout_process_mddi_table(client_data,
  3035. +                    mddi_sharp_deinit_table,
  3036. +                    ARRAY_SIZE(mddi_sharp_deinit_table));
  3037. +       break;
  3038. +   case 1:
  3039. +       printk("deinit tpo panel\n");
  3040. +       trout_process_mddi_table(client_data,
  3041. +                    mddi_tpo_deinit_table,
  3042. +                    ARRAY_SIZE(mddi_tpo_deinit_table));
  3043. +       break;
  3044. +   default:
  3045. +       printk("unknown panel_id: %d\n", panel_id);
  3046. +       ret = -1;
  3047. +   };
  3048. +   client_data->auto_hibernate(client_data, 1);
  3049. +   mutex_lock(&trout_backlight_lock);
  3050. +   trout_set_backlight_level(0);
  3051. +   trout_backlight_off = 1;
  3052. +   mutex_unlock(&trout_backlight_lock);
  3053. +   client_data->remote_write(client_data, 0, SYSCLKENA);
  3054. +   client_data->remote_write(client_data, 1, DPSUS);
  3055. +   return ret;
  3056. +}
  3057. +
  3058. +static int trout_brightness_set(struct backlight_device *bd)
  3059. +{
  3060. +   int intensity;
  3061. +   mutex_lock(&trout_backlight_lock);
  3062. +   intensity = bd->props.brightness;
  3063. +
  3064. +   /* remember last backlight level as requested by user */
  3065. +   trout_backlight_resume_level = intensity;
  3066. +
  3067. +   if(!trout_backlight_off)
  3068. +       trout_set_backlight_level(intensity);
  3069. +   mutex_unlock(&trout_backlight_lock);
  3070. +   return 0;
  3071. +}
  3072. +
  3073. +static int trout_backlight_get_brightness(struct backlight_device *bd){
  3074. +   return bd->props.brightness;
  3075. +}
  3076. +
  3077. +static struct backlight_ops trout_backlight_ops = {
  3078. +   .options = BL_CORE_SUSPENDRESUME,
  3079. +   .update_status  = trout_brightness_set,
  3080. +   .get_brightness = trout_backlight_get_brightness,
  3081. +};
  3082. +
  3083. +static int trout_backlight_probe(struct platform_device *pdev)
  3084. +{
  3085. +   struct backlight_device *bd;
  3086. +   struct backlight_properties props;
  3087. +   memset(&props, 0, sizeof(struct backlight_properties));
  3088. +   props.max_brightness = TROUT_DEFAULT_BACKLIGHT_BRIGHTNESS;
  3089. +   bd = backlight_device_register("trout-backlight", &pdev->dev, NULL, &trout_backlight_ops, &props);
  3090. +   bd->props.max_brightness = TROUT_DEFAULT_BACKLIGHT_BRIGHTNESS;
  3091. +   bd->props.brightness = TROUT_DEFAULT_BACKLIGHT_BRIGHTNESS;
  3092. +   trout_brightness_set(bd);
  3093. +   return 0;
  3094. +}
  3095. +
  3096. +static int trout_backlight_remove(struct platform_device *pdev)
  3097. +{
  3098. +   struct backlight_device *bl = platform_get_drvdata(pdev);
  3099. +   backlight_device_unregister(bl);
  3100. +   return 0;
  3101. +}
  3102. +
  3103. +static struct platform_driver trout_backlight_driver = {
  3104. +   .probe      = trout_backlight_probe,
  3105. +   .remove     = trout_backlight_remove,
  3106. +   .driver     = {
  3107. +       .name       = "trout-backlight",
  3108. +       .owner      = THIS_MODULE,
  3109. +   },
  3110. +};
  3111. +
  3112. +static struct resource resources_msm_fb[] = {
  3113. +   {
  3114. +       .start = MSM_FB_BASE,
  3115. +       .end = MSM_FB_BASE + MSM_FB_SIZE,
  3116. +       .flags = IORESOURCE_MEM,
  3117. +   },
  3118. +};
  3119. +
  3120. +struct msm_mddi_bridge_platform_data toshiba_client_data = {
  3121. +   .init = trout_mddi_toshiba_client_init,
  3122. +   .uninit = trout_mddi_toshiba_client_uninit,
  3123. +   .blank = trout_mddi_panel_blank,
  3124. +   .unblank = trout_mddi_panel_unblank,
  3125. +   .fb_data = {
  3126. +       .xres = 320,
  3127. +       .yres = 480,
  3128. +       .width = 45,
  3129. +       .height = 67,
  3130. +       .output_format = 0,
  3131. +   },
  3132. +};
  3133. +
  3134. +static struct msm_mddi_platform_data mddi_pdata = {
  3135. +   .clk_rate = 122880000,
  3136. +   .power_client = trout_mddi_power_client,
  3137. +   .fb_resource = resources_msm_fb,
  3138. +   .num_clients = 1,
  3139. +   .client_platform_data = {
  3140. +       {
  3141. +           .product_id = (0xd263 << 16 | 0),
  3142. +           .name = "mddi_c_d263_0000",
  3143. +           //.name = "mddi_c_dummy",
  3144. +           .id = 0,
  3145. +           .client_data = &toshiba_client_data,
  3146. +           //.client_data = &toshiba_client_data.fb_data,
  3147. +           .clk_rate = 0,
  3148. +       },
  3149. +   },
  3150. +};
  3151. +
  3152. +static struct platform_device trout_backlight = {
  3153. +   .name = "trout-backlight",
  3154. +};
  3155. +
  3156. +int __init trout_init_panel(void)
  3157. +{
  3158. +   int rc;
  3159. +
  3160. +        if (!machine_is_trout())
  3161. +                return 0;
  3162. +   vreg_mddi_1v5 = vreg_get(0, "gp2");
  3163. +   if (IS_ERR(vreg_mddi_1v5))
  3164. +       return PTR_ERR(vreg_mddi_1v5);
  3165. +   vreg_lcm_2v85 = vreg_get(0, "gp4");
  3166. +   if (IS_ERR(vreg_lcm_2v85))
  3167. +       return PTR_ERR(vreg_lcm_2v85);
  3168. +
  3169. +   trout_new_backlight = system_rev >= 5;
  3170. +   if (trout_new_backlight) {
  3171. +       uint32_t config = PCOM_GPIO_CFG(27, 0, GPIO_OUTPUT,
  3172. +                       GPIO_NO_PULL, GPIO_8MA);
  3173. +       msm_proc_comm(PCOM_RPC_GPIO_TLMM_CONFIG_EX, &config, 0);
  3174. +   }
  3175. +   else {
  3176. +       uint32_t config = PCOM_GPIO_CFG(27, 1, GPIO_OUTPUT,
  3177. +                       GPIO_NO_PULL, GPIO_8MA);
  3178. +       msm_proc_comm(PCOM_RPC_GPIO_TLMM_CONFIG_EX, &config, 0);
  3179. +
  3180. +       gp_clk = clk_get(NULL, "gp_clk");
  3181. +       if (IS_ERR(gp_clk)) {
  3182. +           printk(KERN_ERR "trout_init_panel: could not get gp"
  3183. +                  "clock\n");
  3184. +           gp_clk = NULL;
  3185. +       }
  3186. +       rc = clk_set_rate(gp_clk, 19200000);
  3187. +       if (rc)
  3188. +           printk(KERN_ERR "trout_init_panel: set clock rate "
  3189. +                  "failed\n");
  3190. +   }
  3191. +
  3192. +   rc = platform_device_register(&msm_device_mdp);
  3193. +   if (rc)
  3194. +       return rc;
  3195. +   msm_device_mddi0.dev.platform_data = &mddi_pdata;
  3196. +   rc = platform_device_register(&msm_device_mddi0);
  3197. +   if (rc)
  3198. +       return rc;
  3199. +   platform_device_register(&trout_backlight);
  3200. +   return platform_driver_register(&trout_backlight_driver);
  3201. +}
  3202. +
  3203. +device_initcall(trout_init_panel);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement