Commit 2e5a662d authored by Linus Walleij's avatar Linus Walleij Committed by Wolfram Sang

i2c: cbus-gpio: Switch to use GPIO descriptors

This augments the CBUS GPIO I2C driver to use GPIO
descriptors for clock, sel and data. We drop the platform
data that was only used for carrying GPIO numbers and
use machine descriptor tables instead.
Signed-off-by: default avatarLinus Walleij <linus.walleij@linaro.org>
Tested-by: default avatarAaro Koskinen <aaro.koskinen@iki.fi>
Acked-by: default avatarTony Lindgren <tony@atomide.com>
Signed-off-by: default avatarWolfram Sang <wsa@the-dreams.de>
parent d0051ca5
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include <linux/clkdev.h> #include <linux/clkdev.h>
#include <linux/irq.h> #include <linux/irq.h>
#include <linux/gpio.h> #include <linux/gpio.h>
#include <linux/gpio/machine.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/mutex.h> #include <linux/mutex.h>
...@@ -25,7 +26,6 @@ ...@@ -25,7 +26,6 @@
#include <linux/platform_data/keypad-omap.h> #include <linux/platform_data/keypad-omap.h>
#include <linux/platform_data/lcd-mipid.h> #include <linux/platform_data/lcd-mipid.h>
#include <linux/platform_data/gpio-omap.h> #include <linux/platform_data/gpio-omap.h>
#include <linux/platform_data/i2c-cbus-gpio.h>
#include <asm/mach-types.h> #include <asm/mach-types.h>
#include <asm/mach/arch.h> #include <asm/mach/arch.h>
...@@ -217,18 +217,19 @@ static inline void nokia770_mmc_init(void) ...@@ -217,18 +217,19 @@ static inline void nokia770_mmc_init(void)
#endif #endif
#if IS_ENABLED(CONFIG_I2C_CBUS_GPIO) #if IS_ENABLED(CONFIG_I2C_CBUS_GPIO)
static struct i2c_cbus_platform_data nokia770_cbus_data = { static struct gpiod_lookup_table nokia770_cbus_gpio_table = {
.clk_gpio = OMAP_MPUIO(9), .dev_id = "i2c-cbus-gpio.2",
.dat_gpio = OMAP_MPUIO(10), .table = {
.sel_gpio = OMAP_MPUIO(11), GPIO_LOOKUP_IDX("mpuio", 9, NULL, 0, 0), /* clk */
GPIO_LOOKUP_IDX("mpuio", 10, NULL, 1, 0), /* dat */
GPIO_LOOKUP_IDX("mpuio", 11, NULL, 2, 0), /* sel */
{ },
},
}; };
static struct platform_device nokia770_cbus_device = { static struct platform_device nokia770_cbus_device = {
.name = "i2c-cbus-gpio", .name = "i2c-cbus-gpio",
.id = 2, .id = 2,
.dev = {
.platform_data = &nokia770_cbus_data,
},
}; };
static struct i2c_board_info nokia770_i2c_board_info_2[] __initdata = { static struct i2c_board_info nokia770_i2c_board_info_2[] __initdata = {
...@@ -257,6 +258,7 @@ static void __init nokia770_cbus_init(void) ...@@ -257,6 +258,7 @@ static void __init nokia770_cbus_init(void)
nokia770_i2c_board_info_2[1].irq = gpio_to_irq(tahvo_irq_gpio); nokia770_i2c_board_info_2[1].irq = gpio_to_irq(tahvo_irq_gpio);
i2c_register_board_info(2, nokia770_i2c_board_info_2, i2c_register_board_info(2, nokia770_i2c_board_info_2,
ARRAY_SIZE(nokia770_i2c_board_info_2)); ARRAY_SIZE(nokia770_i2c_board_info_2));
gpiod_add_lookup_table(&nokia770_cbus_gpio_table);
platform_device_register(&nokia770_cbus_device); platform_device_register(&nokia770_cbus_device);
} }
#else /* CONFIG_I2C_CBUS_GPIO */ #else /* CONFIG_I2C_CBUS_GPIO */
......
...@@ -18,16 +18,14 @@ ...@@ -18,16 +18,14 @@
#include <linux/io.h> #include <linux/io.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/gpio.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/of_gpio.h> #include <linux/gpio/consumer.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/platform_data/i2c-cbus-gpio.h>
/* /*
* Bit counts are derived from Nokia implementation. These should be checked * Bit counts are derived from Nokia implementation. These should be checked
...@@ -39,9 +37,9 @@ ...@@ -39,9 +37,9 @@
struct cbus_host { struct cbus_host {
spinlock_t lock; /* host lock */ spinlock_t lock; /* host lock */
struct device *dev; struct device *dev;
int clk_gpio; struct gpio_desc *clk;
int dat_gpio; struct gpio_desc *dat;
int sel_gpio; struct gpio_desc *sel;
}; };
/** /**
...@@ -51,9 +49,9 @@ struct cbus_host { ...@@ -51,9 +49,9 @@ struct cbus_host {
*/ */
static void cbus_send_bit(struct cbus_host *host, unsigned bit) static void cbus_send_bit(struct cbus_host *host, unsigned bit)
{ {
gpio_set_value(host->dat_gpio, bit ? 1 : 0); gpiod_set_value(host->dat, bit ? 1 : 0);
gpio_set_value(host->clk_gpio, 1); gpiod_set_value(host->clk, 1);
gpio_set_value(host->clk_gpio, 0); gpiod_set_value(host->clk, 0);
} }
/** /**
...@@ -78,9 +76,9 @@ static int cbus_receive_bit(struct cbus_host *host) ...@@ -78,9 +76,9 @@ static int cbus_receive_bit(struct cbus_host *host)
{ {
int ret; int ret;
gpio_set_value(host->clk_gpio, 1); gpiod_set_value(host->clk, 1);
ret = gpio_get_value(host->dat_gpio); ret = gpiod_get_value(host->dat);
gpio_set_value(host->clk_gpio, 0); gpiod_set_value(host->clk, 0);
return ret; return ret;
} }
...@@ -123,10 +121,10 @@ static int cbus_transfer(struct cbus_host *host, char rw, unsigned dev, ...@@ -123,10 +121,10 @@ static int cbus_transfer(struct cbus_host *host, char rw, unsigned dev,
spin_lock_irqsave(&host->lock, flags); spin_lock_irqsave(&host->lock, flags);
/* Reset state and start of transfer, SEL stays down during transfer */ /* Reset state and start of transfer, SEL stays down during transfer */
gpio_set_value(host->sel_gpio, 0); gpiod_set_value(host->sel, 0);
/* Set the DAT pin to output */ /* Set the DAT pin to output */
gpio_direction_output(host->dat_gpio, 1); gpiod_direction_output(host->dat, 1);
/* Send the device address */ /* Send the device address */
cbus_send_data(host, dev, CBUS_ADDR_BITS); cbus_send_data(host, dev, CBUS_ADDR_BITS);
...@@ -141,12 +139,12 @@ static int cbus_transfer(struct cbus_host *host, char rw, unsigned dev, ...@@ -141,12 +139,12 @@ static int cbus_transfer(struct cbus_host *host, char rw, unsigned dev,
cbus_send_data(host, data, 16); cbus_send_data(host, data, 16);
ret = 0; ret = 0;
} else { } else {
ret = gpio_direction_input(host->dat_gpio); ret = gpiod_direction_input(host->dat);
if (ret) { if (ret) {
dev_dbg(host->dev, "failed setting direction\n"); dev_dbg(host->dev, "failed setting direction\n");
goto out; goto out;
} }
gpio_set_value(host->clk_gpio, 1); gpiod_set_value(host->clk, 1);
ret = cbus_receive_word(host); ret = cbus_receive_word(host);
if (ret < 0) { if (ret < 0) {
...@@ -156,9 +154,9 @@ static int cbus_transfer(struct cbus_host *host, char rw, unsigned dev, ...@@ -156,9 +154,9 @@ static int cbus_transfer(struct cbus_host *host, char rw, unsigned dev,
} }
/* Indicate end of transfer, SEL goes up until next transfer */ /* Indicate end of transfer, SEL goes up until next transfer */
gpio_set_value(host->sel_gpio, 1); gpiod_set_value(host->sel, 1);
gpio_set_value(host->clk_gpio, 1); gpiod_set_value(host->clk, 1);
gpio_set_value(host->clk_gpio, 0); gpiod_set_value(host->clk, 0);
out: out:
spin_unlock_irqrestore(&host->lock, flags); spin_unlock_irqrestore(&host->lock, flags);
...@@ -214,7 +212,6 @@ static int cbus_i2c_probe(struct platform_device *pdev) ...@@ -214,7 +212,6 @@ static int cbus_i2c_probe(struct platform_device *pdev)
{ {
struct i2c_adapter *adapter; struct i2c_adapter *adapter;
struct cbus_host *chost; struct cbus_host *chost;
int ret;
adapter = devm_kzalloc(&pdev->dev, sizeof(struct i2c_adapter), adapter = devm_kzalloc(&pdev->dev, sizeof(struct i2c_adapter),
GFP_KERNEL); GFP_KERNEL);
...@@ -225,22 +222,20 @@ static int cbus_i2c_probe(struct platform_device *pdev) ...@@ -225,22 +222,20 @@ static int cbus_i2c_probe(struct platform_device *pdev)
if (!chost) if (!chost)
return -ENOMEM; return -ENOMEM;
if (pdev->dev.of_node) { if (gpiod_count(&pdev->dev, NULL) != 3)
struct device_node *dnode = pdev->dev.of_node;
if (of_gpio_count(dnode) != 3)
return -ENODEV;
chost->clk_gpio = of_get_gpio(dnode, 0);
chost->dat_gpio = of_get_gpio(dnode, 1);
chost->sel_gpio = of_get_gpio(dnode, 2);
} else if (dev_get_platdata(&pdev->dev)) {
struct i2c_cbus_platform_data *pdata =
dev_get_platdata(&pdev->dev);
chost->clk_gpio = pdata->clk_gpio;
chost->dat_gpio = pdata->dat_gpio;
chost->sel_gpio = pdata->sel_gpio;
} else {
return -ENODEV; return -ENODEV;
} chost->clk = devm_gpiod_get_index(&pdev->dev, NULL, 0, GPIOD_OUT_LOW);
if (IS_ERR(chost->clk))
return PTR_ERR(chost->clk);
chost->dat = devm_gpiod_get_index(&pdev->dev, NULL, 1, GPIOD_IN);
if (IS_ERR(chost->dat))
return PTR_ERR(chost->dat);
chost->sel = devm_gpiod_get_index(&pdev->dev, NULL, 2, GPIOD_OUT_HIGH);
if (IS_ERR(chost->sel))
return PTR_ERR(chost->sel);
gpiod_set_consumer_name(chost->clk, "CBUS clk");
gpiod_set_consumer_name(chost->dat, "CBUS dat");
gpiod_set_consumer_name(chost->sel, "CBUS sel");
adapter->owner = THIS_MODULE; adapter->owner = THIS_MODULE;
adapter->class = I2C_CLASS_HWMON; adapter->class = I2C_CLASS_HWMON;
...@@ -254,21 +249,6 @@ static int cbus_i2c_probe(struct platform_device *pdev) ...@@ -254,21 +249,6 @@ static int cbus_i2c_probe(struct platform_device *pdev)
spin_lock_init(&chost->lock); spin_lock_init(&chost->lock);
chost->dev = &pdev->dev; chost->dev = &pdev->dev;
ret = devm_gpio_request_one(&pdev->dev, chost->clk_gpio,
GPIOF_OUT_INIT_LOW, "CBUS clk");
if (ret)
return ret;
ret = devm_gpio_request_one(&pdev->dev, chost->dat_gpio, GPIOF_IN,
"CBUS data");
if (ret)
return ret;
ret = devm_gpio_request_one(&pdev->dev, chost->sel_gpio,
GPIOF_OUT_INIT_HIGH, "CBUS sel");
if (ret)
return ret;
i2c_set_adapdata(adapter, chost); i2c_set_adapdata(adapter, chost);
platform_set_drvdata(pdev, adapter); platform_set_drvdata(pdev, adapter);
......
/*
* i2c-cbus-gpio.h - CBUS I2C platform_data definition
*
* Copyright (C) 2004-2009 Nokia Corporation
*
* Written by Felipe Balbi and Aaro Koskinen.
*
* This file is subject to the terms and conditions of the GNU General
* Public License. See the file "COPYING" in the main directory of this
* archive for more details.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __INCLUDE_LINUX_I2C_CBUS_GPIO_H
#define __INCLUDE_LINUX_I2C_CBUS_GPIO_H
struct i2c_cbus_platform_data {
int dat_gpio;
int clk_gpio;
int sel_gpio;
};
#endif /* __INCLUDE_LINUX_I2C_CBUS_GPIO_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment