aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/host/of_mmc_spi.c
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>2013-08-08 06:38:32 -0400
committerChris Ball <cjb@laptop.org>2013-08-24 23:45:22 -0400
commitbf287a90ceedf86e3313ba0dcff606ac5399b39a (patch)
treea3337495e68fde2270c406574774a283c0b4e002 /drivers/mmc/host/of_mmc_spi.c
parent214fc309d1387e822d606a33a10e31cacfe83520 (diff)
mmc: mmc_spi: Support CD/RO GPIOs
Add support for passing CD/RO GPIO numbers directly to the mmc_spi driver instead of relying solely on board code callbacks to retrieve the CD/RO signals values. The driver will enable debouncing on the card detect GPIO if the cd_debounce field is set to a non-zero value. Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com> Signed-off-by: Chris Ball <cjb@laptop.org>
Diffstat (limited to 'drivers/mmc/host/of_mmc_spi.c')
-rw-r--r--drivers/mmc/host/of_mmc_spi.c46
1 files changed, 12 insertions, 34 deletions
diff --git a/drivers/mmc/host/of_mmc_spi.c b/drivers/mmc/host/of_mmc_spi.c
index d720b5e05b9c..6e218fb1a669 100644
--- a/drivers/mmc/host/of_mmc_spi.c
+++ b/drivers/mmc/host/of_mmc_spi.c
@@ -50,25 +50,6 @@ static struct of_mmc_spi *to_of_mmc_spi(struct device *dev)
50 return container_of(dev->platform_data, struct of_mmc_spi, pdata); 50 return container_of(dev->platform_data, struct of_mmc_spi, pdata);
51} 51}
52 52
53static int of_mmc_spi_read_gpio(struct device *dev, int gpio_num)
54{
55 struct of_mmc_spi *oms = to_of_mmc_spi(dev);
56 bool active_low = oms->alow_gpios[gpio_num];
57 bool value = gpio_get_value(oms->gpios[gpio_num]);
58
59 return active_low ^ value;
60}
61
62static int of_mmc_spi_get_cd(struct device *dev)
63{
64 return of_mmc_spi_read_gpio(dev, CD_GPIO);
65}
66
67static int of_mmc_spi_get_ro(struct device *dev)
68{
69 return of_mmc_spi_read_gpio(dev, WP_GPIO);
70}
71
72static int of_mmc_spi_init(struct device *dev, 53static int of_mmc_spi_init(struct device *dev,
73 irqreturn_t (*irqhandler)(int, void *), void *mmc) 54 irqreturn_t (*irqhandler)(int, void *), void *mmc)
74{ 55{
@@ -130,20 +111,22 @@ struct mmc_spi_platform_data *mmc_spi_get_pdata(struct spi_device *spi)
130 if (!gpio_is_valid(oms->gpios[i])) 111 if (!gpio_is_valid(oms->gpios[i]))
131 continue; 112 continue;
132 113
133 ret = gpio_request(oms->gpios[i], dev_name(dev));
134 if (ret < 0) {
135 oms->gpios[i] = -EINVAL;
136 continue;
137 }
138
139 if (gpio_flags & OF_GPIO_ACTIVE_LOW) 114 if (gpio_flags & OF_GPIO_ACTIVE_LOW)
140 oms->alow_gpios[i] = true; 115 oms->alow_gpios[i] = true;
141 } 116 }
142 117
143 if (gpio_is_valid(oms->gpios[CD_GPIO])) 118 if (gpio_is_valid(oms->gpios[CD_GPIO])) {
144 oms->pdata.get_cd = of_mmc_spi_get_cd; 119 oms->pdata.cd_gpio = oms->gpios[CD_GPIO];
145 if (gpio_is_valid(oms->gpios[WP_GPIO])) 120 oms->pdata.flags |= MMC_SPI_USE_CD_GPIO;
146 oms->pdata.get_ro = of_mmc_spi_get_ro; 121 if (!oms->alow_gpios[CD_GPIO])
122 oms->pdata.caps2 |= MMC_CAP2_CD_ACTIVE_HIGH;
123 }
124 if (gpio_is_valid(oms->gpios[WP_GPIO])) {
125 oms->pdata.ro_gpio = oms->gpios[WP_GPIO];
126 oms->pdata.flags |= MMC_SPI_USE_RO_GPIO;
127 if (!oms->alow_gpios[WP_GPIO])
128 oms->pdata.caps2 |= MMC_CAP2_RO_ACTIVE_HIGH;
129 }
147 130
148 oms->detect_irq = irq_of_parse_and_map(np, 0); 131 oms->detect_irq = irq_of_parse_and_map(np, 0);
149 if (oms->detect_irq != 0) { 132 if (oms->detect_irq != 0) {
@@ -166,15 +149,10 @@ void mmc_spi_put_pdata(struct spi_device *spi)
166 struct device *dev = &spi->dev; 149 struct device *dev = &spi->dev;
167 struct device_node *np = dev->of_node; 150 struct device_node *np = dev->of_node;
168 struct of_mmc_spi *oms = to_of_mmc_spi(dev); 151 struct of_mmc_spi *oms = to_of_mmc_spi(dev);
169 int i;
170 152
171 if (!dev->platform_data || !np) 153 if (!dev->platform_data || !np)
172 return; 154 return;
173 155
174 for (i = 0; i < ARRAY_SIZE(oms->gpios); i++) {
175 if (gpio_is_valid(oms->gpios[i]))
176 gpio_free(oms->gpios[i]);
177 }
178 kfree(oms); 156 kfree(oms);
179 dev->platform_data = NULL; 157 dev->platform_data = NULL;
180} 158}