dm355evm_msp.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * dm355evm_msp.c - driver for MSP430 firmware on DM355EVM board
  4. *
  5. * Copyright (C) 2008 David Brownell
  6. */
  7. #include <linux/init.h>
  8. #include <linux/mutex.h>
  9. #include <linux/platform_device.h>
  10. #include <linux/clk.h>
  11. #include <linux/module.h>
  12. #include <linux/err.h>
  13. #include <linux/gpio.h>
  14. #include <linux/gpio/machine.h>
  15. #include <linux/leds.h>
  16. #include <linux/i2c.h>
  17. #include <linux/mfd/dm355evm_msp.h>
  18. /*
  19. * The DM355 is a DaVinci chip with video support but no C64+ DSP. Its
  20. * EVM board has an MSP430 programmed with firmware for various board
  21. * support functions. This driver exposes some of them directly, and
  22. * supports other drivers (e.g. RTC, input) for more complex access.
  23. *
  24. * Because this firmware is entirely board-specific, this file embeds
  25. * knowledge that would be passed as platform_data in a generic driver.
  26. *
  27. * This driver was tested with firmware revision A4.
  28. */
  29. #if IS_ENABLED(CONFIG_INPUT_DM355EVM)
  30. #define msp_has_keyboard() true
  31. #else
  32. #define msp_has_keyboard() false
  33. #endif
  34. #if IS_ENABLED(CONFIG_LEDS_GPIO)
  35. #define msp_has_leds() true
  36. #else
  37. #define msp_has_leds() false
  38. #endif
  39. #if IS_ENABLED(CONFIG_RTC_DRV_DM355EVM)
  40. #define msp_has_rtc() true
  41. #else
  42. #define msp_has_rtc() false
  43. #endif
  44. #if IS_ENABLED(CONFIG_VIDEO_TVP514X)
  45. #define msp_has_tvp() true
  46. #else
  47. #define msp_has_tvp() false
  48. #endif
  49. /*----------------------------------------------------------------------*/
  50. /* REVISIT for paranoia's sake, retry reads/writes on error */
  51. static struct i2c_client *msp430;
  52. /**
  53. * dm355evm_msp_write - Writes a register in dm355evm_msp
  54. * @value: the value to be written
  55. * @reg: register address
  56. *
  57. * Returns result of operation - 0 is success, else negative errno
  58. */
  59. int dm355evm_msp_write(u8 value, u8 reg)
  60. {
  61. return i2c_smbus_write_byte_data(msp430, reg, value);
  62. }
  63. EXPORT_SYMBOL(dm355evm_msp_write);
  64. /**
  65. * dm355evm_msp_read - Reads a register from dm355evm_msp
  66. * @reg: register address
  67. *
  68. * Returns result of operation - value, or negative errno
  69. */
  70. int dm355evm_msp_read(u8 reg)
  71. {
  72. return i2c_smbus_read_byte_data(msp430, reg);
  73. }
  74. EXPORT_SYMBOL(dm355evm_msp_read);
  75. /*----------------------------------------------------------------------*/
  76. /*
  77. * Many of the msp430 pins are just used as fixed-direction GPIOs.
  78. * We could export a few more of them this way, if we wanted.
  79. */
  80. #define MSP_GPIO(bit, reg) ((DM355EVM_MSP_ ## reg) << 3 | (bit))
  81. static const u8 msp_gpios[] = {
  82. /* eight leds */
  83. MSP_GPIO(0, LED), MSP_GPIO(1, LED),
  84. MSP_GPIO(2, LED), MSP_GPIO(3, LED),
  85. MSP_GPIO(4, LED), MSP_GPIO(5, LED),
  86. MSP_GPIO(6, LED), MSP_GPIO(7, LED),
  87. /* SW6 and the NTSC/nPAL jumper */
  88. MSP_GPIO(0, SWITCH1), MSP_GPIO(1, SWITCH1),
  89. MSP_GPIO(2, SWITCH1), MSP_GPIO(3, SWITCH1),
  90. MSP_GPIO(4, SWITCH1),
  91. /* switches on MMC/SD sockets */
  92. /*
  93. * Note: EVMDM355_ECP_VA4.pdf suggests that Bit 2 and 4 should be
  94. * checked for card detection. However on the EVM bit 1 and 3 gives
  95. * this status, for 0 and 1 instance respectively. The pdf also
  96. * suggests that Bit 1 and 3 should be checked for write protection.
  97. * However on the EVM bit 2 and 4 gives this status,for 0 and 1
  98. * instance respectively.
  99. */
  100. MSP_GPIO(2, SDMMC), MSP_GPIO(1, SDMMC), /* mmc0 WP, nCD */
  101. MSP_GPIO(4, SDMMC), MSP_GPIO(3, SDMMC), /* mmc1 WP, nCD */
  102. };
  103. static struct gpio_led evm_leds[] = {
  104. { .name = "dm355evm::ds14",
  105. .default_trigger = "heartbeat", },
  106. { .name = "dm355evm::ds15",
  107. .default_trigger = "mmc0", },
  108. { .name = "dm355evm::ds16",
  109. /* could also be a CE-ATA drive */
  110. .default_trigger = "mmc1", },
  111. { .name = "dm355evm::ds17",
  112. .default_trigger = "nand-disk", },
  113. { .name = "dm355evm::ds18", },
  114. { .name = "dm355evm::ds19", },
  115. { .name = "dm355evm::ds20", },
  116. { .name = "dm355evm::ds21", },
  117. };
  118. static struct gpio_led_platform_data evm_led_data = {
  119. .num_leds = ARRAY_SIZE(evm_leds),
  120. .leds = evm_leds,
  121. };
  122. static struct gpiod_lookup_table evm_leds_gpio_table = {
  123. .dev_id = "leds-gpio",
  124. .table = {
  125. /*
  126. * These GPIOs are on the dm355evm_msp
  127. * GPIO chip at index 0..7
  128. */
  129. GPIO_LOOKUP_IDX("dm355evm_msp", 0, NULL,
  130. 0, GPIO_ACTIVE_LOW),
  131. GPIO_LOOKUP_IDX("dm355evm_msp", 1, NULL,
  132. 1, GPIO_ACTIVE_LOW),
  133. GPIO_LOOKUP_IDX("dm355evm_msp", 2, NULL,
  134. 2, GPIO_ACTIVE_LOW),
  135. GPIO_LOOKUP_IDX("dm355evm_msp", 3, NULL,
  136. 3, GPIO_ACTIVE_LOW),
  137. GPIO_LOOKUP_IDX("dm355evm_msp", 4, NULL,
  138. 4, GPIO_ACTIVE_LOW),
  139. GPIO_LOOKUP_IDX("dm355evm_msp", 5, NULL,
  140. 5, GPIO_ACTIVE_LOW),
  141. GPIO_LOOKUP_IDX("dm355evm_msp", 6, NULL,
  142. 6, GPIO_ACTIVE_LOW),
  143. GPIO_LOOKUP_IDX("dm355evm_msp", 7, NULL,
  144. 7, GPIO_ACTIVE_LOW),
  145. { },
  146. },
  147. };
  148. #define MSP_GPIO_REG(offset) (msp_gpios[(offset)] >> 3)
  149. #define MSP_GPIO_MASK(offset) BIT(msp_gpios[(offset)] & 0x07)
  150. static int msp_gpio_in(struct gpio_chip *chip, unsigned offset)
  151. {
  152. switch (MSP_GPIO_REG(offset)) {
  153. case DM355EVM_MSP_SWITCH1:
  154. case DM355EVM_MSP_SWITCH2:
  155. case DM355EVM_MSP_SDMMC:
  156. return 0;
  157. default:
  158. return -EINVAL;
  159. }
  160. }
  161. static u8 msp_led_cache;
  162. static int msp_gpio_get(struct gpio_chip *chip, unsigned offset)
  163. {
  164. int reg, status;
  165. reg = MSP_GPIO_REG(offset);
  166. status = dm355evm_msp_read(reg);
  167. if (status < 0)
  168. return status;
  169. if (reg == DM355EVM_MSP_LED)
  170. msp_led_cache = status;
  171. return !!(status & MSP_GPIO_MASK(offset));
  172. }
  173. static int msp_gpio_out(struct gpio_chip *chip, unsigned offset, int value)
  174. {
  175. int mask, bits;
  176. /* NOTE: there are some other signals that could be
  177. * packaged as output GPIOs, but they aren't as useful
  178. * as the LEDs ... so for now we don't.
  179. */
  180. if (MSP_GPIO_REG(offset) != DM355EVM_MSP_LED)
  181. return -EINVAL;
  182. mask = MSP_GPIO_MASK(offset);
  183. bits = msp_led_cache;
  184. bits &= ~mask;
  185. if (value)
  186. bits |= mask;
  187. msp_led_cache = bits;
  188. return dm355evm_msp_write(bits, DM355EVM_MSP_LED);
  189. }
  190. static void msp_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
  191. {
  192. msp_gpio_out(chip, offset, value);
  193. }
  194. static struct gpio_chip dm355evm_msp_gpio = {
  195. .label = "dm355evm_msp",
  196. .owner = THIS_MODULE,
  197. .direction_input = msp_gpio_in,
  198. .get = msp_gpio_get,
  199. .direction_output = msp_gpio_out,
  200. .set = msp_gpio_set,
  201. .base = -EINVAL, /* dynamic assignment */
  202. .ngpio = ARRAY_SIZE(msp_gpios),
  203. .can_sleep = true,
  204. };
  205. /*----------------------------------------------------------------------*/
  206. static struct device *add_child(struct i2c_client *client, const char *name,
  207. void *pdata, unsigned pdata_len,
  208. bool can_wakeup, int irq)
  209. {
  210. struct platform_device *pdev;
  211. int status;
  212. pdev = platform_device_alloc(name, -1);
  213. if (!pdev)
  214. return ERR_PTR(-ENOMEM);
  215. device_init_wakeup(&pdev->dev, can_wakeup);
  216. pdev->dev.parent = &client->dev;
  217. if (pdata) {
  218. status = platform_device_add_data(pdev, pdata, pdata_len);
  219. if (status < 0) {
  220. dev_dbg(&pdev->dev, "can't add platform_data\n");
  221. goto put_device;
  222. }
  223. }
  224. if (irq) {
  225. struct resource r = {
  226. .start = irq,
  227. .flags = IORESOURCE_IRQ,
  228. };
  229. status = platform_device_add_resources(pdev, &r, 1);
  230. if (status < 0) {
  231. dev_dbg(&pdev->dev, "can't add irq\n");
  232. goto put_device;
  233. }
  234. }
  235. status = platform_device_add(pdev);
  236. if (status)
  237. goto put_device;
  238. return &pdev->dev;
  239. put_device:
  240. platform_device_put(pdev);
  241. dev_err(&client->dev, "failed to add device %s\n", name);
  242. return ERR_PTR(status);
  243. }
  244. static int add_children(struct i2c_client *client)
  245. {
  246. static const struct {
  247. int offset;
  248. char *label;
  249. } config_inputs[] = {
  250. /* 8 == right after the LEDs */
  251. { 8 + 0, "sw6_1", },
  252. { 8 + 1, "sw6_2", },
  253. { 8 + 2, "sw6_3", },
  254. { 8 + 3, "sw6_4", },
  255. { 8 + 4, "NTSC/nPAL", },
  256. };
  257. struct device *child;
  258. int status;
  259. int i;
  260. /* GPIO-ish stuff */
  261. dm355evm_msp_gpio.parent = &client->dev;
  262. status = gpiochip_add_data(&dm355evm_msp_gpio, NULL);
  263. if (status < 0)
  264. return status;
  265. /* LED output */
  266. if (msp_has_leds()) {
  267. gpiod_add_lookup_table(&evm_leds_gpio_table);
  268. /* NOTE: these are the only fully programmable LEDs
  269. * on the board, since GPIO-61/ds22 (and many signals
  270. * going to DC7) must be used for AEMIF address lines
  271. * unless the top 1 GB of NAND is unused...
  272. */
  273. child = add_child(client, "leds-gpio",
  274. &evm_led_data, sizeof(evm_led_data),
  275. false, 0);
  276. if (IS_ERR(child))
  277. return PTR_ERR(child);
  278. }
  279. /* configuration inputs */
  280. for (i = 0; i < ARRAY_SIZE(config_inputs); i++) {
  281. int gpio = dm355evm_msp_gpio.base + config_inputs[i].offset;
  282. gpio_request_one(gpio, GPIOF_IN, config_inputs[i].label);
  283. /* make it easy for userspace to see these */
  284. gpio_export(gpio, false);
  285. }
  286. /* MMC/SD inputs -- right after the last config input */
  287. if (dev_get_platdata(&client->dev)) {
  288. void (*mmcsd_setup)(unsigned) = dev_get_platdata(&client->dev);
  289. mmcsd_setup(dm355evm_msp_gpio.base + 8 + 5);
  290. }
  291. /* RTC is a 32 bit counter, no alarm */
  292. if (msp_has_rtc()) {
  293. child = add_child(client, "rtc-dm355evm",
  294. NULL, 0, false, 0);
  295. if (IS_ERR(child))
  296. return PTR_ERR(child);
  297. }
  298. /* input from buttons and IR remote (uses the IRQ) */
  299. if (msp_has_keyboard()) {
  300. child = add_child(client, "dm355evm_keys",
  301. NULL, 0, true, client->irq);
  302. if (IS_ERR(child))
  303. return PTR_ERR(child);
  304. }
  305. return 0;
  306. }
  307. /*----------------------------------------------------------------------*/
  308. static void dm355evm_command(unsigned command)
  309. {
  310. int status;
  311. status = dm355evm_msp_write(command, DM355EVM_MSP_COMMAND);
  312. if (status < 0)
  313. dev_err(&msp430->dev, "command %d failure %d\n",
  314. command, status);
  315. }
  316. static void dm355evm_power_off(void)
  317. {
  318. dm355evm_command(MSP_COMMAND_POWEROFF);
  319. }
  320. static int dm355evm_msp_remove(struct i2c_client *client)
  321. {
  322. pm_power_off = NULL;
  323. msp430 = NULL;
  324. return 0;
  325. }
  326. static int
  327. dm355evm_msp_probe(struct i2c_client *client, const struct i2c_device_id *id)
  328. {
  329. int status;
  330. const char *video = msp_has_tvp() ? "TVP5146" : "imager";
  331. if (msp430)
  332. return -EBUSY;
  333. msp430 = client;
  334. /* display revision status; doubles as sanity check */
  335. status = dm355evm_msp_read(DM355EVM_MSP_FIRMREV);
  336. if (status < 0)
  337. goto fail;
  338. dev_info(&client->dev, "firmware v.%02X, %s as video-in\n",
  339. status, video);
  340. /* mux video input: either tvp5146 or some external imager */
  341. status = dm355evm_msp_write(msp_has_tvp() ? 0 : MSP_VIDEO_IMAGER,
  342. DM355EVM_MSP_VIDEO_IN);
  343. if (status < 0)
  344. dev_warn(&client->dev, "error %d muxing %s as video-in\n",
  345. status, video);
  346. /* init LED cache, and turn off the LEDs */
  347. msp_led_cache = 0xff;
  348. dm355evm_msp_write(msp_led_cache, DM355EVM_MSP_LED);
  349. /* export capabilities we support */
  350. status = add_children(client);
  351. if (status < 0)
  352. goto fail;
  353. /* PM hookup */
  354. pm_power_off = dm355evm_power_off;
  355. return 0;
  356. fail:
  357. /* FIXME remove children ... */
  358. dm355evm_msp_remove(client);
  359. return status;
  360. }
  361. static const struct i2c_device_id dm355evm_msp_ids[] = {
  362. { "dm355evm_msp", 0 },
  363. { /* end of list */ },
  364. };
  365. MODULE_DEVICE_TABLE(i2c, dm355evm_msp_ids);
  366. static struct i2c_driver dm355evm_msp_driver = {
  367. .driver.name = "dm355evm_msp",
  368. .id_table = dm355evm_msp_ids,
  369. .probe = dm355evm_msp_probe,
  370. .remove = dm355evm_msp_remove,
  371. };
  372. static int __init dm355evm_msp_init(void)
  373. {
  374. return i2c_add_driver(&dm355evm_msp_driver);
  375. }
  376. subsys_initcall(dm355evm_msp_init);
  377. static void __exit dm355evm_msp_exit(void)
  378. {
  379. i2c_del_driver(&dm355evm_msp_driver);
  380. }
  381. module_exit(dm355evm_msp_exit);
  382. MODULE_DESCRIPTION("Interface to MSP430 firmware on DM355EVM");
  383. MODULE_LICENSE("GPL");