diff options
author | Cory Tusar <cory.tusar@pid1solutions.com> | 2016-02-10 14:32:08 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2016-02-11 22:23:28 -0500 |
commit | 3ca9b1ac28398c6fe0bed335d2d71a35e1c5f7c9 (patch) | |
tree | 7c4bc01765b20b0f281648ff7833a7cbd8b94516 /drivers/misc/eeprom | |
parent | e1379b56e9e88653fcb58cbaa71cd6b1cc304918 (diff) |
misc: eeprom_93xx46: Add support for a GPIO 'select' line.
This commit adds support to the eeprom_93x46 driver allowing a GPIO line
to function as a 'select' or 'enable' signal prior to accessing the
EEPROM.
Signed-off-by: Cory Tusar <cory.tusar@pid1solutions.com>
Tested-by: Chris Healy <chris.healy@zii.aero>
Reviewed-by: Vladimir Zapolskiy <vz@mleia.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/misc/eeprom')
-rw-r--r-- | drivers/misc/eeprom/eeprom_93xx46.c | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/drivers/misc/eeprom/eeprom_93xx46.c b/drivers/misc/eeprom/eeprom_93xx46.c index a3c3136abf3e..f62ab29e293c 100644 --- a/drivers/misc/eeprom/eeprom_93xx46.c +++ b/drivers/misc/eeprom/eeprom_93xx46.c | |||
@@ -10,11 +10,13 @@ | |||
10 | 10 | ||
11 | #include <linux/delay.h> | 11 | #include <linux/delay.h> |
12 | #include <linux/device.h> | 12 | #include <linux/device.h> |
13 | #include <linux/gpio/consumer.h> | ||
13 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
14 | #include <linux/module.h> | 15 | #include <linux/module.h> |
15 | #include <linux/mutex.h> | 16 | #include <linux/mutex.h> |
16 | #include <linux/of.h> | 17 | #include <linux/of.h> |
17 | #include <linux/of_device.h> | 18 | #include <linux/of_device.h> |
19 | #include <linux/of_gpio.h> | ||
18 | #include <linux/slab.h> | 20 | #include <linux/slab.h> |
19 | #include <linux/spi/spi.h> | 21 | #include <linux/spi/spi.h> |
20 | #include <linux/sysfs.h> | 22 | #include <linux/sysfs.h> |
@@ -343,6 +345,20 @@ static ssize_t eeprom_93xx46_store_erase(struct device *dev, | |||
343 | } | 345 | } |
344 | static DEVICE_ATTR(erase, S_IWUSR, NULL, eeprom_93xx46_store_erase); | 346 | static DEVICE_ATTR(erase, S_IWUSR, NULL, eeprom_93xx46_store_erase); |
345 | 347 | ||
348 | static void select_assert(void *context) | ||
349 | { | ||
350 | struct eeprom_93xx46_dev *edev = context; | ||
351 | |||
352 | gpiod_set_value_cansleep(edev->pdata->select, 1); | ||
353 | } | ||
354 | |||
355 | static void select_deassert(void *context) | ||
356 | { | ||
357 | struct eeprom_93xx46_dev *edev = context; | ||
358 | |||
359 | gpiod_set_value_cansleep(edev->pdata->select, 0); | ||
360 | } | ||
361 | |||
346 | static const struct of_device_id eeprom_93xx46_of_table[] = { | 362 | static const struct of_device_id eeprom_93xx46_of_table[] = { |
347 | { .compatible = "eeprom-93xx46", }, | 363 | { .compatible = "eeprom-93xx46", }, |
348 | { .compatible = "atmel,at93c46d", .data = &atmel_at93c46d_data, }, | 364 | { .compatible = "atmel,at93c46d", .data = &atmel_at93c46d_data, }, |
@@ -357,6 +373,8 @@ static int eeprom_93xx46_probe_dt(struct spi_device *spi) | |||
357 | struct device_node *np = spi->dev.of_node; | 373 | struct device_node *np = spi->dev.of_node; |
358 | struct eeprom_93xx46_platform_data *pd; | 374 | struct eeprom_93xx46_platform_data *pd; |
359 | u32 tmp; | 375 | u32 tmp; |
376 | int gpio; | ||
377 | enum of_gpio_flags of_flags; | ||
360 | int ret; | 378 | int ret; |
361 | 379 | ||
362 | pd = devm_kzalloc(&spi->dev, sizeof(*pd), GFP_KERNEL); | 380 | pd = devm_kzalloc(&spi->dev, sizeof(*pd), GFP_KERNEL); |
@@ -381,6 +399,23 @@ static int eeprom_93xx46_probe_dt(struct spi_device *spi) | |||
381 | if (of_property_read_bool(np, "read-only")) | 399 | if (of_property_read_bool(np, "read-only")) |
382 | pd->flags |= EE_READONLY; | 400 | pd->flags |= EE_READONLY; |
383 | 401 | ||
402 | gpio = of_get_named_gpio_flags(np, "select-gpios", 0, &of_flags); | ||
403 | if (gpio_is_valid(gpio)) { | ||
404 | unsigned long flags = | ||
405 | of_flags == OF_GPIO_ACTIVE_LOW ? GPIOF_ACTIVE_LOW : 0; | ||
406 | |||
407 | ret = devm_gpio_request_one(&spi->dev, gpio, flags, | ||
408 | "eeprom_93xx46_select"); | ||
409 | if (ret) | ||
410 | return ret; | ||
411 | |||
412 | pd->select = gpio_to_desc(gpio); | ||
413 | pd->prepare = select_assert; | ||
414 | pd->finish = select_deassert; | ||
415 | |||
416 | gpiod_direction_output(pd->select, 0); | ||
417 | } | ||
418 | |||
384 | if (of_id->data) { | 419 | if (of_id->data) { |
385 | const struct eeprom_93xx46_devtype_data *data = of_id->data; | 420 | const struct eeprom_93xx46_devtype_data *data = of_id->data; |
386 | 421 | ||