206-spi-ath79-make-chipselect-logic-more-flexible.patch 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. From 7008284716403237f6bc7d7590b3ed073555bd56 Mon Sep 17 00:00:00 2001
  2. From: Gabor Juhos <[email protected]>
  3. Date: Wed, 11 Jan 2012 22:25:11 +0100
  4. Subject: [PATCH 34/34] spi/ath79: make chipselect logic more flexible
  5. Signed-off-by: Gabor Juhos <[email protected]>
  6. ---
  7. arch/mips/ath79/mach-ap121.c | 6 ++
  8. arch/mips/ath79/mach-ap136.c | 6 ++
  9. arch/mips/ath79/mach-ap81.c | 6 ++
  10. arch/mips/ath79/mach-db120.c | 6 ++
  11. arch/mips/ath79/mach-pb44.c | 6 ++
  12. arch/mips/ath79/mach-ubnt-xm.c | 6 ++
  13. .../include/asm/mach-ath79/ath79_spi_platform.h | 8 ++-
  14. drivers/spi/spi-ath79.c | 67 +++++++++++++-------
  15. 8 files changed, 88 insertions(+), 23 deletions(-)
  16. --- a/arch/mips/ath79/mach-ap121.c
  17. +++ b/arch/mips/ath79/mach-ap121.c
  18. @@ -58,12 +58,18 @@ static struct gpio_keys_button ap121_gpi
  19. }
  20. };
  21. +static struct ath79_spi_controller_data ap121_spi0_data = {
  22. + .cs_type = ATH79_SPI_CS_TYPE_INTERNAL,
  23. + .cs_line = 0,
  24. +};
  25. +
  26. static struct spi_board_info ap121_spi_info[] = {
  27. {
  28. .bus_num = 0,
  29. .chip_select = 0,
  30. .max_speed_hz = 25000000,
  31. .modalias = "mx25l1606e",
  32. + .controller_data = &ap121_spi0_data,
  33. }
  34. };
  35. --- a/arch/mips/ath79/mach-ap136.c
  36. +++ b/arch/mips/ath79/mach-ap136.c
  37. @@ -98,12 +98,18 @@ static struct gpio_keys_button ap136_gpi
  38. },
  39. };
  40. +static struct ath79_spi_controller_data ap136_spi0_data = {
  41. + .cs_type = ATH79_SPI_CS_TYPE_INTERNAL,
  42. + .cs_line = 0,
  43. +};
  44. +
  45. static struct spi_board_info ap136_spi_info[] = {
  46. {
  47. .bus_num = 0,
  48. .chip_select = 0,
  49. .max_speed_hz = 25000000,
  50. .modalias = "mx25l6405d",
  51. + .controller_data = &ap136_spi0_data,
  52. }
  53. };
  54. --- a/arch/mips/ath79/mach-ap81.c
  55. +++ b/arch/mips/ath79/mach-ap81.c
  56. @@ -67,12 +67,18 @@ static struct gpio_keys_button ap81_gpio
  57. }
  58. };
  59. +static struct ath79_spi_controller_data ap81_spi0_data = {
  60. + .cs_type = ATH79_SPI_CS_TYPE_INTERNAL,
  61. + .cs_line = 0,
  62. +};
  63. +
  64. static struct spi_board_info ap81_spi_info[] = {
  65. {
  66. .bus_num = 0,
  67. .chip_select = 0,
  68. .max_speed_hz = 25000000,
  69. .modalias = "m25p64",
  70. + .controller_data = &ap81_spi0_data,
  71. }
  72. };
  73. --- a/arch/mips/ath79/mach-db120.c
  74. +++ b/arch/mips/ath79/mach-db120.c
  75. @@ -76,12 +76,18 @@ static struct gpio_keys_button db120_gpi
  76. },
  77. };
  78. +static struct ath79_spi_controller_data db120_spi0_data = {
  79. + .cs_type = ATH79_SPI_CS_TYPE_INTERNAL,
  80. + .cs_line = 0,
  81. +};
  82. +
  83. static struct spi_board_info db120_spi_info[] = {
  84. {
  85. .bus_num = 0,
  86. .chip_select = 0,
  87. .max_speed_hz = 25000000,
  88. .modalias = "s25sl064a",
  89. + .controller_data = &db120_spi0_data,
  90. }
  91. };
  92. --- a/arch/mips/ath79/mach-pb44.c
  93. +++ b/arch/mips/ath79/mach-pb44.c
  94. @@ -87,12 +87,18 @@ static struct gpio_keys_button pb44_gpio
  95. }
  96. };
  97. +static struct ath79_spi_controller_data pb44_spi0_data = {
  98. + .cs_type = ATH79_SPI_CS_TYPE_INTERNAL,
  99. + .cs_line = 0,
  100. +};
  101. +
  102. static struct spi_board_info pb44_spi_info[] = {
  103. {
  104. .bus_num = 0,
  105. .chip_select = 0,
  106. .max_speed_hz = 25000000,
  107. .modalias = "m25p64",
  108. + .controller_data = &pb44_spi0_data,
  109. },
  110. };
  111. --- a/arch/mips/ath79/mach-ubnt-xm.c
  112. +++ b/arch/mips/ath79/mach-ubnt-xm.c
  113. @@ -65,12 +65,18 @@ static struct gpio_keys_button ubnt_xm_g
  114. }
  115. };
  116. +static struct ath79_spi_controller_data ubnt_xm_spi0_data = {
  117. + .cs_type = ATH79_SPI_CS_TYPE_INTERNAL,
  118. + .cs_line = 0,
  119. +};
  120. +
  121. static struct spi_board_info ubnt_xm_spi_info[] = {
  122. {
  123. .bus_num = 0,
  124. .chip_select = 0,
  125. .max_speed_hz = 25000000,
  126. .modalias = "mx25l6405d",
  127. + .controller_data = &ubnt_xm_spi0_data,
  128. }
  129. };
  130. --- a/arch/mips/include/asm/mach-ath79/ath79_spi_platform.h
  131. +++ b/arch/mips/include/asm/mach-ath79/ath79_spi_platform.h
  132. @@ -16,8 +16,14 @@ struct ath79_spi_platform_data {
  133. unsigned num_chipselect;
  134. };
  135. +enum ath79_spi_cs_type {
  136. + ATH79_SPI_CS_TYPE_INTERNAL,
  137. + ATH79_SPI_CS_TYPE_GPIO,
  138. +};
  139. +
  140. struct ath79_spi_controller_data {
  141. - unsigned gpio;
  142. + enum ath79_spi_cs_type cs_type;
  143. + unsigned cs_line;
  144. };
  145. #endif /* _ATH79_SPI_PLATFORM_H */
  146. --- a/drivers/spi/spi-ath79.c
  147. +++ b/drivers/spi/spi-ath79.c
  148. @@ -35,6 +35,8 @@
  149. #define ATH79_SPI_RRW_DELAY_FACTOR 12000
  150. #define MHZ (1000 * 1000)
  151. +#define ATH79_SPI_CS_LINE_MAX 2
  152. +
  153. struct ath79_spi {
  154. struct spi_bitbang bitbang;
  155. u32 ioc_base;
  156. @@ -69,6 +71,7 @@ static void ath79_spi_chipselect(struct
  157. {
  158. struct ath79_spi *sp = ath79_spidev_to_sp(spi);
  159. int cs_high = (spi->mode & SPI_CS_HIGH) ? is_active : !is_active;
  160. + struct ath79_spi_controller_data *cdata = spi->controller_data;
  161. if (is_active) {
  162. /* set initial clock polarity */
  163. @@ -80,20 +83,24 @@ static void ath79_spi_chipselect(struct
  164. ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, sp->ioc_base);
  165. }
  166. - if (spi->chip_select) {
  167. - struct ath79_spi_controller_data *cdata = spi->controller_data;
  168. -
  169. - /* SPI is normally active-low */
  170. - gpio_set_value(cdata->gpio, cs_high);
  171. - } else {
  172. + switch (cdata->cs_type) {
  173. + case ATH79_SPI_CS_TYPE_INTERNAL:
  174. if (cs_high)
  175. - sp->ioc_base |= AR71XX_SPI_IOC_CS0;
  176. + sp->ioc_base |= AR71XX_SPI_IOC_CS(cdata->cs_line);
  177. else
  178. - sp->ioc_base &= ~AR71XX_SPI_IOC_CS0;
  179. + sp->ioc_base &= ~AR71XX_SPI_IOC_CS(cdata->cs_line);
  180. ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, sp->ioc_base);
  181. - }
  182. + break;
  183. + case ATH79_SPI_CS_TYPE_GPIO:
  184. + /* SPI is normally active-low */
  185. + if (gpio_cansleep(cdata->cs_line))
  186. + gpio_set_value_cansleep(cdata->cs_line, cs_high);
  187. + else
  188. + gpio_set_value(cdata->cs_line, cs_high);
  189. + break;
  190. + }
  191. }
  192. static void ath79_spi_enable(struct ath79_spi *sp)
  193. @@ -120,24 +127,30 @@ static void ath79_spi_disable(struct ath
  194. static int ath79_spi_setup_cs(struct spi_device *spi)
  195. {
  196. struct ath79_spi_controller_data *cdata;
  197. + unsigned long flags;
  198. int status;
  199. cdata = spi->controller_data;
  200. - if (spi->chip_select && !cdata)
  201. + if (!cdata)
  202. return -EINVAL;
  203. status = 0;
  204. - if (spi->chip_select) {
  205. - unsigned long flags;
  206. + switch (cdata->cs_type) {
  207. + case ATH79_SPI_CS_TYPE_INTERNAL:
  208. + if (cdata->cs_line > ATH79_SPI_CS_LINE_MAX)
  209. + status = -EINVAL;
  210. + break;
  211. + case ATH79_SPI_CS_TYPE_GPIO:
  212. flags = GPIOF_DIR_OUT;
  213. if (spi->mode & SPI_CS_HIGH)
  214. flags |= GPIOF_INIT_LOW;
  215. else
  216. flags |= GPIOF_INIT_HIGH;
  217. - status = gpio_request_one(cdata->gpio, flags,
  218. + status = gpio_request_one(cdata->cs_line, flags,
  219. dev_name(&spi->dev));
  220. + break;
  221. }
  222. return status;
  223. @@ -145,9 +158,19 @@ static int ath79_spi_setup_cs(struct spi
  224. static void ath79_spi_cleanup_cs(struct spi_device *spi)
  225. {
  226. - if (spi->chip_select) {
  227. - struct ath79_spi_controller_data *cdata = spi->controller_data;
  228. - gpio_free(cdata->gpio);
  229. + struct ath79_spi_controller_data *cdata;
  230. +
  231. + cdata = spi->controller_data;
  232. + if (!cdata)
  233. + return;
  234. +
  235. + switch (cdata->cs_type) {
  236. + case ATH79_SPI_CS_TYPE_INTERNAL:
  237. + /* nothing to do */
  238. + break;
  239. + case ATH79_SPI_CS_TYPE_GPIO:
  240. + gpio_free(cdata->cs_line);
  241. + break;
  242. }
  243. }
  244. @@ -155,6 +178,9 @@ static int ath79_spi_setup(struct spi_de
  245. {
  246. int status = 0;
  247. + if (spi->controller_data == NULL)
  248. + return -EINVAL;
  249. +
  250. if (spi->bits_per_word > 32)
  251. return -EINVAL;
  252. @@ -215,6 +241,10 @@ static int ath79_spi_probe(struct platfo
  253. unsigned long rate;
  254. int ret;
  255. + pdata = pdev->dev.platform_data;
  256. + if (!pdata)
  257. + return -EINVAL;
  258. +
  259. master = spi_alloc_master(&pdev->dev, sizeof(*sp));
  260. if (master == NULL) {
  261. dev_err(&pdev->dev, "failed to allocate spi master\n");
  262. @@ -224,14 +254,10 @@ static int ath79_spi_probe(struct platfo
  263. sp = spi_master_get_devdata(master);
  264. platform_set_drvdata(pdev, sp);
  265. - pdata = pdev->dev.platform_data;
  266. -
  267. master->setup = ath79_spi_setup;
  268. master->cleanup = ath79_spi_cleanup;
  269. - if (pdata) {
  270. - master->bus_num = pdata->bus_num;
  271. - master->num_chipselect = pdata->num_chipselect;
  272. - }
  273. + master->bus_num = pdata->bus_num;
  274. + master->num_chipselect = pdata->num_chipselect;
  275. sp->bitbang.master = spi_master_get(master);
  276. sp->bitbang.chipselect = ath79_spi_chipselect;