diff options
author | Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> | 2013-08-08 06:38:32 -0400 |
---|---|---|
committer | Chris Ball <cjb@laptop.org> | 2013-08-24 23:45:22 -0400 |
commit | bf287a90ceedf86e3313ba0dcff606ac5399b39a (patch) | |
tree | a3337495e68fde2270c406574774a283c0b4e002 /drivers/mmc/host/of_mmc_spi.c | |
parent | 214fc309d1387e822d606a33a10e31cacfe83520 (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.c | 46 |
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 | ||
53 | static 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 | |||
62 | static int of_mmc_spi_get_cd(struct device *dev) | ||
63 | { | ||
64 | return of_mmc_spi_read_gpio(dev, CD_GPIO); | ||
65 | } | ||
66 | |||
67 | static int of_mmc_spi_get_ro(struct device *dev) | ||
68 | { | ||
69 | return of_mmc_spi_read_gpio(dev, WP_GPIO); | ||
70 | } | ||
71 | |||
72 | static int of_mmc_spi_init(struct device *dev, | 53 | static 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 | } |