diff options
author | Alexander Shiyan <shc_work@mail.ru> | 2016-06-08 13:02:06 -0400 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2016-06-14 05:19:41 -0400 |
commit | b36581df7e788b674a4efbb8da7fe4a00c207e8b (patch) | |
tree | 0a9f92930205bcf034c80316ab5c162f970e7842 | |
parent | 1a695a905c18548062509178b98bc91e67510864 (diff) |
spi: imx: Using existing properties for chipselects
Patch reuse existing "chip_select" and "cs_gpio(s)" fields from SPI core.
Signed-off-by: Alexander Shiyan <shc_work@mail.ru>
Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r-- | drivers/spi/spi-imx.c | 124 |
1 files changed, 58 insertions, 66 deletions
diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c index 50769078e72e..cbcfb8b70b21 100644 --- a/drivers/spi/spi-imx.c +++ b/drivers/spi/spi-imx.c | |||
@@ -60,7 +60,6 @@ struct spi_imx_config { | |||
60 | unsigned int speed_hz; | 60 | unsigned int speed_hz; |
61 | unsigned int bpw; | 61 | unsigned int bpw; |
62 | unsigned int mode; | 62 | unsigned int mode; |
63 | u8 cs; | ||
64 | }; | 63 | }; |
65 | 64 | ||
66 | enum spi_imx_devtype { | 65 | enum spi_imx_devtype { |
@@ -76,7 +75,7 @@ struct spi_imx_data; | |||
76 | 75 | ||
77 | struct spi_imx_devtype_data { | 76 | struct spi_imx_devtype_data { |
78 | void (*intctrl)(struct spi_imx_data *, int); | 77 | void (*intctrl)(struct spi_imx_data *, int); |
79 | int (*config)(struct spi_imx_data *, struct spi_imx_config *); | 78 | int (*config)(struct spi_device *, struct spi_imx_config *); |
80 | void (*trigger)(struct spi_imx_data *); | 79 | void (*trigger)(struct spi_imx_data *); |
81 | int (*rx_available)(struct spi_imx_data *); | 80 | int (*rx_available)(struct spi_imx_data *); |
82 | void (*reset)(struct spi_imx_data *); | 81 | void (*reset)(struct spi_imx_data *); |
@@ -112,7 +111,6 @@ struct spi_imx_data { | |||
112 | struct completion dma_tx_completion; | 111 | struct completion dma_tx_completion; |
113 | 112 | ||
114 | const struct spi_imx_devtype_data *devtype_data; | 113 | const struct spi_imx_devtype_data *devtype_data; |
115 | int chipselect[0]; | ||
116 | }; | 114 | }; |
117 | 115 | ||
118 | static inline int is_imx27_cspi(struct spi_imx_data *d) | 116 | static inline int is_imx27_cspi(struct spi_imx_data *d) |
@@ -334,9 +332,10 @@ static void __maybe_unused mx51_ecspi_trigger(struct spi_imx_data *spi_imx) | |||
334 | writel(reg, spi_imx->base + MX51_ECSPI_CTRL); | 332 | writel(reg, spi_imx->base + MX51_ECSPI_CTRL); |
335 | } | 333 | } |
336 | 334 | ||
337 | static int __maybe_unused mx51_ecspi_config(struct spi_imx_data *spi_imx, | 335 | static int __maybe_unused mx51_ecspi_config(struct spi_device *spi, |
338 | struct spi_imx_config *config) | 336 | struct spi_imx_config *config) |
339 | { | 337 | { |
338 | struct spi_imx_data *spi_imx = spi_master_get_devdata(spi->master); | ||
340 | u32 ctrl = MX51_ECSPI_CTRL_ENABLE; | 339 | u32 ctrl = MX51_ECSPI_CTRL_ENABLE; |
341 | u32 clk = config->speed_hz, delay, reg; | 340 | u32 clk = config->speed_hz, delay, reg; |
342 | u32 cfg = readl(spi_imx->base + MX51_ECSPI_CONFIG); | 341 | u32 cfg = readl(spi_imx->base + MX51_ECSPI_CONFIG); |
@@ -355,28 +354,28 @@ static int __maybe_unused mx51_ecspi_config(struct spi_imx_data *spi_imx, | |||
355 | spi_imx->spi_bus_clk = clk; | 354 | spi_imx->spi_bus_clk = clk; |
356 | 355 | ||
357 | /* set chip select to use */ | 356 | /* set chip select to use */ |
358 | ctrl |= MX51_ECSPI_CTRL_CS(config->cs); | 357 | ctrl |= MX51_ECSPI_CTRL_CS(spi->chip_select); |
359 | 358 | ||
360 | ctrl |= (config->bpw - 1) << MX51_ECSPI_CTRL_BL_OFFSET; | 359 | ctrl |= (config->bpw - 1) << MX51_ECSPI_CTRL_BL_OFFSET; |
361 | 360 | ||
362 | cfg |= MX51_ECSPI_CONFIG_SBBCTRL(config->cs); | 361 | cfg |= MX51_ECSPI_CONFIG_SBBCTRL(spi->chip_select); |
363 | 362 | ||
364 | if (config->mode & SPI_CPHA) | 363 | if (config->mode & SPI_CPHA) |
365 | cfg |= MX51_ECSPI_CONFIG_SCLKPHA(config->cs); | 364 | cfg |= MX51_ECSPI_CONFIG_SCLKPHA(spi->chip_select); |
366 | else | 365 | else |
367 | cfg &= ~MX51_ECSPI_CONFIG_SCLKPHA(config->cs); | 366 | cfg &= ~MX51_ECSPI_CONFIG_SCLKPHA(spi->chip_select); |
368 | 367 | ||
369 | if (config->mode & SPI_CPOL) { | 368 | if (config->mode & SPI_CPOL) { |
370 | cfg |= MX51_ECSPI_CONFIG_SCLKPOL(config->cs); | 369 | cfg |= MX51_ECSPI_CONFIG_SCLKPOL(spi->chip_select); |
371 | cfg |= MX51_ECSPI_CONFIG_SCLKCTL(config->cs); | 370 | cfg |= MX51_ECSPI_CONFIG_SCLKCTL(spi->chip_select); |
372 | } else { | 371 | } else { |
373 | cfg &= ~MX51_ECSPI_CONFIG_SCLKPOL(config->cs); | 372 | cfg &= ~MX51_ECSPI_CONFIG_SCLKPOL(spi->chip_select); |
374 | cfg &= ~MX51_ECSPI_CONFIG_SCLKCTL(config->cs); | 373 | cfg &= ~MX51_ECSPI_CONFIG_SCLKCTL(spi->chip_select); |
375 | } | 374 | } |
376 | if (config->mode & SPI_CS_HIGH) | 375 | if (config->mode & SPI_CS_HIGH) |
377 | cfg |= MX51_ECSPI_CONFIG_SSBPOL(config->cs); | 376 | cfg |= MX51_ECSPI_CONFIG_SSBPOL(spi->chip_select); |
378 | else | 377 | else |
379 | cfg &= ~MX51_ECSPI_CONFIG_SSBPOL(config->cs); | 378 | cfg &= ~MX51_ECSPI_CONFIG_SSBPOL(spi->chip_select); |
380 | 379 | ||
381 | if (spi_imx->usedma) | 380 | if (spi_imx->usedma) |
382 | ctrl |= MX51_ECSPI_CTRL_SMC; | 381 | ctrl |= MX51_ECSPI_CTRL_SMC; |
@@ -480,11 +479,11 @@ static void __maybe_unused mx31_trigger(struct spi_imx_data *spi_imx) | |||
480 | writel(reg, spi_imx->base + MXC_CSPICTRL); | 479 | writel(reg, spi_imx->base + MXC_CSPICTRL); |
481 | } | 480 | } |
482 | 481 | ||
483 | static int __maybe_unused mx31_config(struct spi_imx_data *spi_imx, | 482 | static int __maybe_unused mx31_config(struct spi_device *spi, |
484 | struct spi_imx_config *config) | 483 | struct spi_imx_config *config) |
485 | { | 484 | { |
485 | struct spi_imx_data *spi_imx = spi_master_get_devdata(spi->master); | ||
486 | unsigned int reg = MX31_CSPICTRL_ENABLE | MX31_CSPICTRL_MASTER; | 486 | unsigned int reg = MX31_CSPICTRL_ENABLE | MX31_CSPICTRL_MASTER; |
487 | int cs = spi_imx->chipselect[config->cs]; | ||
488 | 487 | ||
489 | reg |= spi_imx_clkdiv_2(spi_imx->spi_clk, config->speed_hz) << | 488 | reg |= spi_imx_clkdiv_2(spi_imx->spi_clk, config->speed_hz) << |
490 | MX31_CSPICTRL_DR_SHIFT; | 489 | MX31_CSPICTRL_DR_SHIFT; |
@@ -502,8 +501,8 @@ static int __maybe_unused mx31_config(struct spi_imx_data *spi_imx, | |||
502 | reg |= MX31_CSPICTRL_POL; | 501 | reg |= MX31_CSPICTRL_POL; |
503 | if (config->mode & SPI_CS_HIGH) | 502 | if (config->mode & SPI_CS_HIGH) |
504 | reg |= MX31_CSPICTRL_SSPOL; | 503 | reg |= MX31_CSPICTRL_SSPOL; |
505 | if (cs < 0) | 504 | if (spi->cs_gpio < 0) |
506 | reg |= (cs + 32) << | 505 | reg |= (spi->cs_gpio + 32) << |
507 | (is_imx35_cspi(spi_imx) ? MX35_CSPICTRL_CS_SHIFT : | 506 | (is_imx35_cspi(spi_imx) ? MX35_CSPICTRL_CS_SHIFT : |
508 | MX31_CSPICTRL_CS_SHIFT); | 507 | MX31_CSPICTRL_CS_SHIFT); |
509 | 508 | ||
@@ -558,11 +557,11 @@ static void __maybe_unused mx21_trigger(struct spi_imx_data *spi_imx) | |||
558 | writel(reg, spi_imx->base + MXC_CSPICTRL); | 557 | writel(reg, spi_imx->base + MXC_CSPICTRL); |
559 | } | 558 | } |
560 | 559 | ||
561 | static int __maybe_unused mx21_config(struct spi_imx_data *spi_imx, | 560 | static int __maybe_unused mx21_config(struct spi_device *spi, |
562 | struct spi_imx_config *config) | 561 | struct spi_imx_config *config) |
563 | { | 562 | { |
563 | struct spi_imx_data *spi_imx = spi_master_get_devdata(spi->master); | ||
564 | unsigned int reg = MX21_CSPICTRL_ENABLE | MX21_CSPICTRL_MASTER; | 564 | unsigned int reg = MX21_CSPICTRL_ENABLE | MX21_CSPICTRL_MASTER; |
565 | int cs = spi_imx->chipselect[config->cs]; | ||
566 | unsigned int max = is_imx27_cspi(spi_imx) ? 16 : 18; | 565 | unsigned int max = is_imx27_cspi(spi_imx) ? 16 : 18; |
567 | 566 | ||
568 | reg |= spi_imx_clkdiv_1(spi_imx->spi_clk, config->speed_hz, max) << | 567 | reg |= spi_imx_clkdiv_1(spi_imx->spi_clk, config->speed_hz, max) << |
@@ -575,8 +574,8 @@ static int __maybe_unused mx21_config(struct spi_imx_data *spi_imx, | |||
575 | reg |= MX21_CSPICTRL_POL; | 574 | reg |= MX21_CSPICTRL_POL; |
576 | if (config->mode & SPI_CS_HIGH) | 575 | if (config->mode & SPI_CS_HIGH) |
577 | reg |= MX21_CSPICTRL_SSPOL; | 576 | reg |= MX21_CSPICTRL_SSPOL; |
578 | if (cs < 0) | 577 | if (spi->cs_gpio < 0) |
579 | reg |= (cs + 32) << MX21_CSPICTRL_CS_SHIFT; | 578 | reg |= (spi->cs_gpio + 32) << MX21_CSPICTRL_CS_SHIFT; |
580 | 579 | ||
581 | writel(reg, spi_imx->base + MXC_CSPICTRL); | 580 | writel(reg, spi_imx->base + MXC_CSPICTRL); |
582 | 581 | ||
@@ -625,9 +624,10 @@ static void __maybe_unused mx1_trigger(struct spi_imx_data *spi_imx) | |||
625 | writel(reg, spi_imx->base + MXC_CSPICTRL); | 624 | writel(reg, spi_imx->base + MXC_CSPICTRL); |
626 | } | 625 | } |
627 | 626 | ||
628 | static int __maybe_unused mx1_config(struct spi_imx_data *spi_imx, | 627 | static int __maybe_unused mx1_config(struct spi_device *spi, |
629 | struct spi_imx_config *config) | 628 | struct spi_imx_config *config) |
630 | { | 629 | { |
630 | struct spi_imx_data *spi_imx = spi_master_get_devdata(spi->master); | ||
631 | unsigned int reg = MX1_CSPICTRL_ENABLE | MX1_CSPICTRL_MASTER; | 631 | unsigned int reg = MX1_CSPICTRL_ENABLE | MX1_CSPICTRL_MASTER; |
632 | 632 | ||
633 | reg |= spi_imx_clkdiv_2(spi_imx->spi_clk, config->speed_hz) << | 633 | reg |= spi_imx_clkdiv_2(spi_imx->spi_clk, config->speed_hz) << |
@@ -747,15 +747,13 @@ MODULE_DEVICE_TABLE(of, spi_imx_dt_ids); | |||
747 | 747 | ||
748 | static void spi_imx_chipselect(struct spi_device *spi, int is_active) | 748 | static void spi_imx_chipselect(struct spi_device *spi, int is_active) |
749 | { | 749 | { |
750 | struct spi_imx_data *spi_imx = spi_master_get_devdata(spi->master); | ||
751 | int gpio = spi_imx->chipselect[spi->chip_select]; | ||
752 | int active = is_active != BITBANG_CS_INACTIVE; | 750 | int active = is_active != BITBANG_CS_INACTIVE; |
753 | int dev_is_lowactive = !(spi->mode & SPI_CS_HIGH); | 751 | int dev_is_lowactive = !(spi->mode & SPI_CS_HIGH); |
754 | 752 | ||
755 | if (!gpio_is_valid(gpio)) | 753 | if (!gpio_is_valid(spi->cs_gpio)) |
756 | return; | 754 | return; |
757 | 755 | ||
758 | gpio_set_value(gpio, dev_is_lowactive ^ active); | 756 | gpio_set_value(spi->cs_gpio, dev_is_lowactive ^ active); |
759 | } | 757 | } |
760 | 758 | ||
761 | static void spi_imx_push(struct spi_imx_data *spi_imx) | 759 | static void spi_imx_push(struct spi_imx_data *spi_imx) |
@@ -860,7 +858,6 @@ static int spi_imx_setupxfer(struct spi_device *spi, | |||
860 | config.bpw = t ? t->bits_per_word : spi->bits_per_word; | 858 | config.bpw = t ? t->bits_per_word : spi->bits_per_word; |
861 | config.speed_hz = t ? t->speed_hz : spi->max_speed_hz; | 859 | config.speed_hz = t ? t->speed_hz : spi->max_speed_hz; |
862 | config.mode = spi->mode; | 860 | config.mode = spi->mode; |
863 | config.cs = spi->chip_select; | ||
864 | 861 | ||
865 | if (!config.speed_hz) | 862 | if (!config.speed_hz) |
866 | config.speed_hz = spi->max_speed_hz; | 863 | config.speed_hz = spi->max_speed_hz; |
@@ -891,7 +888,7 @@ static int spi_imx_setupxfer(struct spi_device *spi, | |||
891 | return ret; | 888 | return ret; |
892 | } | 889 | } |
893 | 890 | ||
894 | spi_imx->devtype_data->config(spi_imx, &config); | 891 | spi_imx->devtype_data->config(spi, &config); |
895 | 892 | ||
896 | return 0; | 893 | return 0; |
897 | } | 894 | } |
@@ -1080,14 +1077,12 @@ static int spi_imx_transfer(struct spi_device *spi, | |||
1080 | 1077 | ||
1081 | static int spi_imx_setup(struct spi_device *spi) | 1078 | static int spi_imx_setup(struct spi_device *spi) |
1082 | { | 1079 | { |
1083 | struct spi_imx_data *spi_imx = spi_master_get_devdata(spi->master); | ||
1084 | int gpio = spi_imx->chipselect[spi->chip_select]; | ||
1085 | |||
1086 | dev_dbg(&spi->dev, "%s: mode %d, %u bpw, %d hz\n", __func__, | 1080 | dev_dbg(&spi->dev, "%s: mode %d, %u bpw, %d hz\n", __func__, |
1087 | spi->mode, spi->bits_per_word, spi->max_speed_hz); | 1081 | spi->mode, spi->bits_per_word, spi->max_speed_hz); |
1088 | 1082 | ||
1089 | if (gpio_is_valid(gpio)) | 1083 | if (gpio_is_valid(spi->cs_gpio)) |
1090 | gpio_direction_output(gpio, spi->mode & SPI_CS_HIGH ? 0 : 1); | 1084 | gpio_direction_output(spi->cs_gpio, |
1085 | spi->mode & SPI_CS_HIGH ? 0 : 1); | ||
1091 | 1086 | ||
1092 | spi_imx_chipselect(spi, BITBANG_CS_INACTIVE); | 1087 | spi_imx_chipselect(spi, BITBANG_CS_INACTIVE); |
1093 | 1088 | ||
@@ -1137,31 +1132,21 @@ static int spi_imx_probe(struct platform_device *pdev) | |||
1137 | struct spi_master *master; | 1132 | struct spi_master *master; |
1138 | struct spi_imx_data *spi_imx; | 1133 | struct spi_imx_data *spi_imx; |
1139 | struct resource *res; | 1134 | struct resource *res; |
1140 | int i, ret, num_cs, irq; | 1135 | int i, ret, irq; |
1141 | 1136 | ||
1142 | if (!np && !mxc_platform_info) { | 1137 | if (!np && !mxc_platform_info) { |
1143 | dev_err(&pdev->dev, "can't get the platform data\n"); | 1138 | dev_err(&pdev->dev, "can't get the platform data\n"); |
1144 | return -EINVAL; | 1139 | return -EINVAL; |
1145 | } | 1140 | } |
1146 | 1141 | ||
1147 | ret = of_property_read_u32(np, "fsl,spi-num-chipselects", &num_cs); | 1142 | master = spi_alloc_master(&pdev->dev, sizeof(struct spi_imx_data)); |
1148 | if (ret < 0) { | ||
1149 | if (mxc_platform_info) | ||
1150 | num_cs = mxc_platform_info->num_chipselect; | ||
1151 | else | ||
1152 | return ret; | ||
1153 | } | ||
1154 | |||
1155 | master = spi_alloc_master(&pdev->dev, | ||
1156 | sizeof(struct spi_imx_data) + sizeof(int) * num_cs); | ||
1157 | if (!master) | 1143 | if (!master) |
1158 | return -ENOMEM; | 1144 | return -ENOMEM; |
1159 | 1145 | ||
1160 | platform_set_drvdata(pdev, master); | 1146 | platform_set_drvdata(pdev, master); |
1161 | 1147 | ||
1162 | master->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 32); | 1148 | master->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 32); |
1163 | master->bus_num = pdev->id; | 1149 | master->bus_num = np ? -1 : pdev->id; |
1164 | master->num_chipselect = num_cs; | ||
1165 | 1150 | ||
1166 | spi_imx = spi_master_get_devdata(master); | 1151 | spi_imx = spi_master_get_devdata(master); |
1167 | spi_imx->bitbang.master = master; | 1152 | spi_imx->bitbang.master = master; |
@@ -1170,22 +1155,16 @@ static int spi_imx_probe(struct platform_device *pdev) | |||
1170 | spi_imx->devtype_data = of_id ? of_id->data : | 1155 | spi_imx->devtype_data = of_id ? of_id->data : |
1171 | (struct spi_imx_devtype_data *)pdev->id_entry->driver_data; | 1156 | (struct spi_imx_devtype_data *)pdev->id_entry->driver_data; |
1172 | 1157 | ||
1173 | for (i = 0; i < master->num_chipselect; i++) { | 1158 | if (mxc_platform_info) { |
1174 | int cs_gpio = of_get_named_gpio(np, "cs-gpios", i); | 1159 | master->num_chipselect = mxc_platform_info->num_chipselect; |
1175 | if (!gpio_is_valid(cs_gpio) && mxc_platform_info) | 1160 | master->cs_gpios = devm_kzalloc(&master->dev, |
1176 | cs_gpio = mxc_platform_info->chipselect[i]; | 1161 | sizeof(int) * master->num_chipselect, GFP_KERNEL); |
1177 | 1162 | if (!master->cs_gpios) | |
1178 | spi_imx->chipselect[i] = cs_gpio; | 1163 | return -ENOMEM; |
1179 | if (!gpio_is_valid(cs_gpio)) | ||
1180 | continue; | ||
1181 | 1164 | ||
1182 | ret = devm_gpio_request(&pdev->dev, spi_imx->chipselect[i], | 1165 | for (i = 0; i < master->num_chipselect; i++) |
1183 | DRIVER_NAME); | 1166 | master->cs_gpios[i] = mxc_platform_info->chipselect[i]; |
1184 | if (ret) { | 1167 | } |
1185 | dev_err(&pdev->dev, "can't get cs gpios\n"); | ||
1186 | goto out_master_put; | ||
1187 | } | ||
1188 | } | ||
1189 | 1168 | ||
1190 | spi_imx->bitbang.chipselect = spi_imx_chipselect; | 1169 | spi_imx->bitbang.chipselect = spi_imx_chipselect; |
1191 | spi_imx->bitbang.setup_transfer = spi_imx_setupxfer; | 1170 | spi_imx->bitbang.setup_transfer = spi_imx_setupxfer; |
@@ -1267,6 +1246,19 @@ static int spi_imx_probe(struct platform_device *pdev) | |||
1267 | goto out_clk_put; | 1246 | goto out_clk_put; |
1268 | } | 1247 | } |
1269 | 1248 | ||
1249 | for (i = 0; i < master->num_chipselect; i++) { | ||
1250 | if (!gpio_is_valid(master->cs_gpios[i])) | ||
1251 | continue; | ||
1252 | |||
1253 | ret = devm_gpio_request(&pdev->dev, master->cs_gpios[i], | ||
1254 | DRIVER_NAME); | ||
1255 | if (ret) { | ||
1256 | dev_err(&pdev->dev, "Can't get CS GPIO %i\n", | ||
1257 | master->cs_gpios[i]); | ||
1258 | goto out_clk_put; | ||
1259 | } | ||
1260 | } | ||
1261 | |||
1270 | dev_info(&pdev->dev, "probed\n"); | 1262 | dev_info(&pdev->dev, "probed\n"); |
1271 | 1263 | ||
1272 | clk_disable(spi_imx->clk_ipg); | 1264 | clk_disable(spi_imx->clk_ipg); |