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 | ||
