aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/spi/spi-mt65xx.c
diff options
context:
space:
mode:
authorLeilk Liu <leilk.liu@mediatek.com>2015-10-26 04:09:44 -0400
committerMark Brown <broonie@kernel.org>2015-10-27 00:33:42 -0400
commit37457607ecaffe56718a0e423548edeb3d4a11b7 (patch)
treee37b60c5ff7f4e83cd76eaaf05640c146088669f /drivers/spi/spi-mt65xx.c
parent58a984c79a68d508ccfccf4b82c0eaf7f487c399 (diff)
spi: mediatek: mt8173 spi multiple devices support
mt8173 IC spi HW has 4 gpio group, it's possible to support max <= 4 slave devices, even mtk spi HW is not congruent to spi core. 1. When a device do a spi_message transfer, spi HW should know which pad-group this device is on, and then writes pad-select register. 2. Mtk pad-select register just selects which MISO pin HW will receive data. For example, pad-select=1(select spi1 pins), HW just receives data from spi1 MISO, but it still send waveform to all 4 group cs/clk/mosi. If cs pin in other groups is still spi mode, after spi1 is selected(by active cs pin), devices on other group will also be selected. Signed-off-by: Leilk Liu <leilk.liu@mediatek.com> Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'drivers/spi/spi-mt65xx.c')
-rw-r--r--drivers/spi/spi-mt65xx.c65
1 files changed, 52 insertions, 13 deletions
diff --git a/drivers/spi/spi-mt65xx.c b/drivers/spi/spi-mt65xx.c
index 406695a42e19..563954a61424 100644
--- a/drivers/spi/spi-mt65xx.c
+++ b/drivers/spi/spi-mt65xx.c
@@ -20,6 +20,7 @@
20#include <linux/ioport.h> 20#include <linux/ioport.h>
21#include <linux/module.h> 21#include <linux/module.h>
22#include <linux/of.h> 22#include <linux/of.h>
23#include <linux/of_gpio.h>
23#include <linux/platform_device.h> 24#include <linux/platform_device.h>
24#include <linux/platform_data/spi-mt65xx.h> 25#include <linux/platform_data/spi-mt65xx.h>
25#include <linux/pm_runtime.h> 26#include <linux/pm_runtime.h>
@@ -84,7 +85,8 @@ struct mtk_spi_compatible {
84struct mtk_spi { 85struct mtk_spi {
85 void __iomem *base; 86 void __iomem *base;
86 u32 state; 87 u32 state;
87 u32 pad_sel; 88 int pad_num;
89 u32 *pad_sel;
88 struct clk *parent_clk, *sel_clk, *spi_clk; 90 struct clk *parent_clk, *sel_clk, *spi_clk;
89 struct spi_transfer *cur_transfer; 91 struct spi_transfer *cur_transfer;
90 u32 xfer_len; 92 u32 xfer_len;
@@ -188,7 +190,8 @@ static int mtk_spi_prepare_message(struct spi_master *master,
188 190
189 /* pad select */ 191 /* pad select */
190 if (mdata->dev_comp->need_pad_sel) 192 if (mdata->dev_comp->need_pad_sel)
191 writel(mdata->pad_sel, mdata->base + SPI_PAD_SEL_REG); 193 writel(mdata->pad_sel[spi->chip_select],
194 mdata->base + SPI_PAD_SEL_REG);
192 195
193 return 0; 196 return 0;
194} 197}
@@ -407,6 +410,9 @@ static int mtk_spi_setup(struct spi_device *spi)
407 if (!spi->controller_data) 410 if (!spi->controller_data)
408 spi->controller_data = (void *)&mtk_default_chip_info; 411 spi->controller_data = (void *)&mtk_default_chip_info;
409 412
413 if (mdata->dev_comp->need_pad_sel)
414 gpio_direction_output(spi->cs_gpio, !(spi->mode & SPI_CS_HIGH));
415
410 return 0; 416 return 0;
411} 417}
412 418
@@ -481,7 +487,7 @@ static int mtk_spi_probe(struct platform_device *pdev)
481 struct mtk_spi *mdata; 487 struct mtk_spi *mdata;
482 const struct of_device_id *of_id; 488 const struct of_device_id *of_id;
483 struct resource *res; 489 struct resource *res;
484 int irq, ret; 490 int i, irq, ret;
485 491
486 master = spi_alloc_master(&pdev->dev, sizeof(*mdata)); 492 master = spi_alloc_master(&pdev->dev, sizeof(*mdata));
487 if (!master) { 493 if (!master) {
@@ -512,21 +518,34 @@ static int mtk_spi_probe(struct platform_device *pdev)
512 master->flags = SPI_MASTER_MUST_TX; 518 master->flags = SPI_MASTER_MUST_TX;
513 519
514 if (mdata->dev_comp->need_pad_sel) { 520 if (mdata->dev_comp->need_pad_sel) {
515 ret = of_property_read_u32(pdev->dev.of_node, 521 mdata->pad_num = of_property_count_u32_elems(
516 "mediatek,pad-select", 522 pdev->dev.of_node,
517 &mdata->pad_sel); 523 "mediatek,pad-select");
518 if (ret) { 524 if (mdata->pad_num < 0) {
519 dev_err(&pdev->dev, "failed to read pad select: %d\n", 525 dev_err(&pdev->dev,
520 ret); 526 "No 'mediatek,pad-select' property\n");
527 ret = -EINVAL;
521 goto err_put_master; 528 goto err_put_master;
522 } 529 }
523 530
524 if (mdata->pad_sel > MT8173_SPI_MAX_PAD_SEL) { 531 mdata->pad_sel = devm_kmalloc_array(&pdev->dev, mdata->pad_num,
525 dev_err(&pdev->dev, "wrong pad-select: %u\n", 532 sizeof(u32), GFP_KERNEL);
526 mdata->pad_sel); 533 if (!mdata->pad_sel) {
527 ret = -EINVAL; 534 ret = -ENOMEM;
528 goto err_put_master; 535 goto err_put_master;
529 } 536 }
537
538 for (i = 0; i < mdata->pad_num; i++) {
539 of_property_read_u32_index(pdev->dev.of_node,
540 "mediatek,pad-select",
541 i, &mdata->pad_sel[i]);
542 if (mdata->pad_sel[i] > MT8173_SPI_MAX_PAD_SEL) {
543 dev_err(&pdev->dev, "wrong pad-sel[%d]: %u\n",
544 i, mdata->pad_sel[i]);
545 ret = -EINVAL;
546 goto err_put_master;
547 }
548 }
530 } 549 }
531 550
532 platform_set_drvdata(pdev, master); 551 platform_set_drvdata(pdev, master);
@@ -604,6 +623,26 @@ static int mtk_spi_probe(struct platform_device *pdev)
604 goto err_put_master; 623 goto err_put_master;
605 } 624 }
606 625
626 if (mdata->dev_comp->need_pad_sel) {
627 if (mdata->pad_num != master->num_chipselect) {
628 dev_err(&pdev->dev,
629 "pad_num does not match num_chipselect(%d != %d)\n",
630 mdata->pad_num, master->num_chipselect);
631 ret = -EINVAL;
632 goto err_put_master;
633 }
634
635 for (i = 0; i < master->num_chipselect; i++) {
636 ret = devm_gpio_request(&pdev->dev, master->cs_gpios[i],
637 dev_name(&pdev->dev));
638 if (ret) {
639 dev_err(&pdev->dev,
640 "can't get CS GPIO %i\n", i);
641 goto err_put_master;
642 }
643 }
644 }
645
607 return 0; 646 return 0;
608 647
609err_disable_clk: 648err_disable_clk: