board-dm646x-evm.c 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354
  1. /*
  2. * TI DaVinci DM646X EVM board
  3. *
  4. * Derived from: arch/arm/mach-davinci/board-evm.c
  5. * Copyright (C) 2006 Texas Instruments.
  6. *
  7. * (C) 2007-2008, MontaVista Software, Inc.
  8. *
  9. * This file is licensed under the terms of the GNU General Public License
  10. * version 2. This program is licensed "as is" without any warranty of any
  11. * kind, whether express or implied.
  12. *
  13. */
  14. /**************************************************************************
  15. * Included Files
  16. **************************************************************************/
  17. #include <linux/kernel.h>
  18. #include <linux/module.h>
  19. #include <linux/init.h>
  20. #include <linux/fs.h>
  21. #include <linux/major.h>
  22. #include <linux/root_dev.h>
  23. #include <linux/dma-mapping.h>
  24. #include <linux/serial.h>
  25. #include <linux/serial_8250.h>
  26. #include <linux/leds.h>
  27. #include <linux/gpio.h>
  28. #include <linux/io.h>
  29. #include <linux/platform_device.h>
  30. #include <linux/i2c.h>
  31. #include <linux/i2c/at24.h>
  32. #include <linux/i2c/pcf857x.h>
  33. #include <linux/etherdevice.h>
  34. #include <asm/setup.h>
  35. #include <asm/mach-types.h>
  36. #include <asm/mach/arch.h>
  37. #include <asm/mach/map.h>
  38. #include <asm/mach/flash.h>
  39. #include <mach/dm646x.h>
  40. #include <mach/common.h>
  41. #include <mach/psc.h>
  42. #include <mach/serial.h>
  43. #include <mach/i2c.h>
  44. #include <mach/mmc.h>
  45. #include <mach/emac.h>
  46. #if defined(CONFIG_BLK_DEV_PALMCHIP_BK3710) || \
  47. defined(CONFIG_BLK_DEV_PALMCHIP_BK3710_MODULE)
  48. #define HAS_ATA 1
  49. #else
  50. #define HAS_ATA 0
  51. #endif
  52. /* CPLD Register 0 bits to control ATA */
  53. #define DM646X_EVM_ATA_RST BIT(0)
  54. #define DM646X_EVM_ATA_PWD BIT(1)
  55. #define DM646X_EVM_PHY_MASK (0x2)
  56. #define DM646X_EVM_MDIO_FREQUENCY (2200000) /* PHY bus frequency */
  57. static struct davinci_uart_config uart_config __initdata = {
  58. .enabled_uarts = (1 << 0),
  59. };
  60. /* CPLD Register 0 Client: used for I/O Control */
  61. static int cpld_reg0_probe(struct i2c_client *client,
  62. const struct i2c_device_id *id)
  63. {
  64. if (HAS_ATA) {
  65. u8 data;
  66. struct i2c_msg msg[2] = {
  67. {
  68. .addr = client->addr,
  69. .flags = I2C_M_RD,
  70. .len = 1,
  71. .buf = &data,
  72. },
  73. {
  74. .addr = client->addr,
  75. .flags = 0,
  76. .len = 1,
  77. .buf = &data,
  78. },
  79. };
  80. /* Clear ATA_RSTn and ATA_PWD bits to enable ATA operation. */
  81. i2c_transfer(client->adapter, msg, 1);
  82. data &= ~(DM646X_EVM_ATA_RST | DM646X_EVM_ATA_PWD);
  83. i2c_transfer(client->adapter, msg + 1, 1);
  84. }
  85. return 0;
  86. }
  87. static const struct i2c_device_id cpld_reg_ids[] = {
  88. { "cpld_reg0", 0, },
  89. { },
  90. };
  91. static struct i2c_driver dm6467evm_cpld_driver = {
  92. .driver.name = "cpld_reg0",
  93. .id_table = cpld_reg_ids,
  94. .probe = cpld_reg0_probe,
  95. };
  96. /* LEDS */
  97. static struct gpio_led evm_leds[] = {
  98. { .name = "DS1", .active_low = 1, },
  99. { .name = "DS2", .active_low = 1, },
  100. { .name = "DS3", .active_low = 1, },
  101. { .name = "DS4", .active_low = 1, },
  102. };
  103. static __initconst struct gpio_led_platform_data evm_led_data = {
  104. .num_leds = ARRAY_SIZE(evm_leds),
  105. .leds = evm_leds,
  106. };
  107. static struct platform_device *evm_led_dev;
  108. static int evm_led_setup(struct i2c_client *client, int gpio,
  109. unsigned int ngpio, void *c)
  110. {
  111. struct gpio_led *leds = evm_leds;
  112. int status;
  113. while (ngpio--) {
  114. leds->gpio = gpio++;
  115. leds++;
  116. };
  117. evm_led_dev = platform_device_alloc("leds-gpio", 0);
  118. platform_device_add_data(evm_led_dev, &evm_led_data,
  119. sizeof(evm_led_data));
  120. evm_led_dev->dev.parent = &client->dev;
  121. status = platform_device_add(evm_led_dev);
  122. if (status < 0) {
  123. platform_device_put(evm_led_dev);
  124. evm_led_dev = NULL;
  125. }
  126. return status;
  127. }
  128. static int evm_led_teardown(struct i2c_client *client, int gpio,
  129. unsigned ngpio, void *c)
  130. {
  131. if (evm_led_dev) {
  132. platform_device_unregister(evm_led_dev);
  133. evm_led_dev = NULL;
  134. }
  135. return 0;
  136. }
  137. static int evm_sw_gpio[4] = { -EINVAL, -EINVAL, -EINVAL, -EINVAL };
  138. static int evm_sw_setup(struct i2c_client *client, int gpio,
  139. unsigned ngpio, void *c)
  140. {
  141. int status;
  142. int i;
  143. char label[10];
  144. for (i = 0; i < 4; ++i) {
  145. snprintf(label, 10, "user_sw%d", i);
  146. status = gpio_request(gpio, label);
  147. if (status)
  148. goto out_free;
  149. evm_sw_gpio[i] = gpio++;
  150. status = gpio_direction_input(evm_sw_gpio[i]);
  151. if (status) {
  152. gpio_free(evm_sw_gpio[i]);
  153. evm_sw_gpio[i] = -EINVAL;
  154. goto out_free;
  155. }
  156. status = gpio_export(evm_sw_gpio[i], 0);
  157. if (status) {
  158. gpio_free(evm_sw_gpio[i]);
  159. evm_sw_gpio[i] = -EINVAL;
  160. goto out_free;
  161. }
  162. }
  163. return status;
  164. out_free:
  165. for (i = 0; i < 4; ++i) {
  166. if (evm_sw_gpio[i] != -EINVAL) {
  167. gpio_free(evm_sw_gpio[i]);
  168. evm_sw_gpio[i] = -EINVAL;
  169. }
  170. }
  171. return status;
  172. }
  173. static int evm_sw_teardown(struct i2c_client *client, int gpio,
  174. unsigned ngpio, void *c)
  175. {
  176. int i;
  177. for (i = 0; i < 4; ++i) {
  178. if (evm_sw_gpio[i] != -EINVAL) {
  179. gpio_unexport(evm_sw_gpio[i]);
  180. gpio_free(evm_sw_gpio[i]);
  181. evm_sw_gpio[i] = -EINVAL;
  182. }
  183. }
  184. return 0;
  185. }
  186. static int evm_pcf_setup(struct i2c_client *client, int gpio,
  187. unsigned int ngpio, void *c)
  188. {
  189. int status;
  190. if (ngpio < 8)
  191. return -EINVAL;
  192. status = evm_sw_setup(client, gpio, 4, c);
  193. if (status)
  194. return status;
  195. return evm_led_setup(client, gpio+4, 4, c);
  196. }
  197. static int evm_pcf_teardown(struct i2c_client *client, int gpio,
  198. unsigned int ngpio, void *c)
  199. {
  200. BUG_ON(ngpio < 8);
  201. evm_sw_teardown(client, gpio, 4, c);
  202. evm_led_teardown(client, gpio+4, 4, c);
  203. return 0;
  204. }
  205. static struct pcf857x_platform_data pcf_data = {
  206. .gpio_base = DAVINCI_N_GPIO+1,
  207. .setup = evm_pcf_setup,
  208. .teardown = evm_pcf_teardown,
  209. };
  210. /* Most of this EEPROM is unused, but U-Boot uses some data:
  211. * - 0x7f00, 6 bytes Ethernet Address
  212. * - ... newer boards may have more
  213. */
  214. static struct at24_platform_data eeprom_info = {
  215. .byte_len = (256*1024) / 8,
  216. .page_size = 64,
  217. .flags = AT24_FLAG_ADDR16,
  218. .setup = davinci_get_mac_addr,
  219. .context = (void *)0x7f00,
  220. };
  221. static u8 dm646x_iis_serializer_direction[] = {
  222. TX_MODE, RX_MODE, INACTIVE_MODE, INACTIVE_MODE,
  223. };
  224. static u8 dm646x_dit_serializer_direction[] = {
  225. TX_MODE,
  226. };
  227. static struct snd_platform_data dm646x_evm_snd_data[] = {
  228. {
  229. .tx_dma_offset = 0x400,
  230. .rx_dma_offset = 0x400,
  231. .op_mode = DAVINCI_MCASP_IIS_MODE,
  232. .num_serializer = ARRAY_SIZE(dm646x_iis_serializer_direction),
  233. .tdm_slots = 2,
  234. .serial_dir = dm646x_iis_serializer_direction,
  235. .eventq_no = EVENTQ_0,
  236. },
  237. {
  238. .tx_dma_offset = 0x400,
  239. .rx_dma_offset = 0,
  240. .op_mode = DAVINCI_MCASP_DIT_MODE,
  241. .num_serializer = ARRAY_SIZE(dm646x_dit_serializer_direction),
  242. .tdm_slots = 32,
  243. .serial_dir = dm646x_dit_serializer_direction,
  244. .eventq_no = EVENTQ_0,
  245. },
  246. };
  247. static struct i2c_board_info __initdata i2c_info[] = {
  248. {
  249. I2C_BOARD_INFO("24c256", 0x50),
  250. .platform_data = &eeprom_info,
  251. },
  252. {
  253. I2C_BOARD_INFO("pcf8574a", 0x38),
  254. .platform_data = &pcf_data,
  255. },
  256. {
  257. I2C_BOARD_INFO("cpld_reg0", 0x3a),
  258. },
  259. {
  260. I2C_BOARD_INFO("tlv320aic33", 0x18),
  261. }
  262. };
  263. static struct davinci_i2c_platform_data i2c_pdata = {
  264. .bus_freq = 100 /* kHz */,
  265. .bus_delay = 0 /* usec */,
  266. };
  267. static void __init evm_init_i2c(void)
  268. {
  269. davinci_init_i2c(&i2c_pdata);
  270. i2c_add_driver(&dm6467evm_cpld_driver);
  271. i2c_register_board_info(1, i2c_info, ARRAY_SIZE(i2c_info));
  272. }
  273. static void __init davinci_map_io(void)
  274. {
  275. dm646x_init();
  276. }
  277. static __init void evm_init(void)
  278. {
  279. struct davinci_soc_info *soc_info = &davinci_soc_info;
  280. evm_init_i2c();
  281. davinci_serial_init(&uart_config);
  282. dm646x_init_mcasp0(&dm646x_evm_snd_data[0]);
  283. dm646x_init_mcasp1(&dm646x_evm_snd_data[1]);
  284. if (HAS_ATA)
  285. dm646x_init_ide();
  286. soc_info->emac_pdata->phy_mask = DM646X_EVM_PHY_MASK;
  287. soc_info->emac_pdata->mdio_max_freq = DM646X_EVM_MDIO_FREQUENCY;
  288. }
  289. static __init void davinci_dm646x_evm_irq_init(void)
  290. {
  291. davinci_irq_init();
  292. }
  293. MACHINE_START(DAVINCI_DM6467_EVM, "DaVinci DM646x EVM")
  294. .phys_io = IO_PHYS,
  295. .io_pg_offst = (__IO_ADDRESS(IO_PHYS) >> 18) & 0xfffc,
  296. .boot_params = (0x80000100),
  297. .map_io = davinci_map_io,
  298. .init_irq = davinci_dm646x_evm_irq_init,
  299. .timer = &davinci_timer,
  300. .init_machine = evm_init,
  301. MACHINE_END