BigW Consortium Gitlab

Commit 1f09d35a by Ashish Syal

updated expander driver to allow working with gpio expander

parent 5e4bb54a
......@@ -16,72 +16,72 @@
#define TRI_LED_BLU (7)
#define TRI_LED_GRN (15)
#define TRI_LED_RED (10)
#define BUZZER (0)
struct expander_device {
struct platform_device *pdev;
atomic_t generic_led_val, pcm_sel_val, sdio_sel_val, buzzer_val,
atomic_t generic_led_val, pcm_sel_val, sdio_sel_val,
tri_led_blu_val, tri_led_red_val, tri_led_grn_val;
int gpio_expander_base;
};
#define CREATE_SYSFS_DEFN(_var, _offset) \
#define CREATE_SYSFS_DEFN(_var, _offset,_valchange) \
static ssize_t _var##_show(struct device *dev, struct device_attribute *attr, \
char *buf) \
char *buf) \
{ \
struct expander_device* exp = dev_get_drvdata(dev); \
return sprintf(buf, "%d\n", atomic_read(&exp->_var##_val)); \
struct expander_device* exp = dev_get_drvdata(dev); \
return sprintf(buf, "%d\n", atomic_read(&exp->_var##_val)); \
} \
static int _var##_store(struct device *dev, struct device_attribute *attr, \
const char *buf, size_t count) \
const char *buf, size_t count) \
{ \
struct expander_device* exp = dev_get_drvdata(dev); \
u8 val; \
int ret; \
struct expander_device* exp = dev_get_drvdata(dev); \
u8 val; \
int ret; \
\
ret = kstrtou8(buf, 10, &val); \
if (ret || val > 1) \
return -EINVAL; \
ret = kstrtou8(buf, 10, &val); \
if (ret || val > 1) \
return -EINVAL; \
if (_valchange) \
{ val = !val;} \
gpio_set_value_cansleep(exp->gpio_expander_base + _offset, val); \
atomic_set(&exp->_var##_val, val); \
dev_info(dev, "Setting GPIO %d to %d\n", \
exp->gpio_expander_base + _offset, val); \
\
gpio_set_value_cansleep(exp->gpio_expander_base + _offset, val); \
atomic_set(&exp->_var##_val, val); \
dev_info(dev, "Setting GPIO %d to %d\n", \
exp->gpio_expander_base + _offset, val); \
\
return count; \
return count; \
} \
static DEVICE_ATTR_RW(_var)
CREATE_SYSFS_DEFN(generic_led, GENERIC_LED);
CREATE_SYSFS_DEFN(pcm_sel, PCM_SEL);
CREATE_SYSFS_DEFN(sdio_sel, SDIO_SEL);
CREATE_SYSFS_DEFN(tri_led_blu, TRI_LED_BLU);
CREATE_SYSFS_DEFN(tri_led_red, TRI_LED_RED);
CREATE_SYSFS_DEFN(tri_led_grn, TRI_LED_GRN);
CREATE_SYSFS_DEFN(buzzer, BUZZER);
CREATE_SYSFS_DEFN(generic_led, GENERIC_LED,false);
CREATE_SYSFS_DEFN(pcm_sel, PCM_SEL,false);
CREATE_SYSFS_DEFN(sdio_sel, SDIO_SEL,false);
CREATE_SYSFS_DEFN(tri_led_blu, TRI_LED_BLU,true);
CREATE_SYSFS_DEFN(tri_led_red, TRI_LED_RED,true);
CREATE_SYSFS_DEFN(tri_led_grn, TRI_LED_GRN,true);
static int gpio_initial_status(struct platform_device *pdev,
struct device_attribute *attr,
int expander_gpio_offset, int gpio_output_level,
atomic_t *atomic_val)
atomic_t *atomic_val, bool is_open_drain,
bool is_active_low)
{
struct expander_device *exp = dev_get_drvdata(&pdev->dev);
const int gpio_num = exp->gpio_expander_base + expander_gpio_offset;
const int gpio_num = exp->gpio_expander_base + expander_gpio_offset;
int ret = devm_gpio_request_one(
&pdev->dev, gpio_num,
(GPIOF_DIR_OUT |
(gpio_output_level ? GPIOF_INIT_HIGH : GPIOF_INIT_LOW)),
(gpio_output_level ? GPIOF_INIT_HIGH : GPIOF_INIT_LOW) |
(is_open_drain ? GPIOF_OPEN_DRAIN : 0)),
attr->attr.name);
if (ret != 0) {
dev_err(&pdev->dev, "Couldn't request GPIO %d\n", gpio_num);
return ret;
}
atomic_set(atomic_val, gpio_output_level);
atomic_set(atomic_val, gpio_output_level);
ret = device_create_file(&pdev->dev, attr);
if (ret != 0) {
......@@ -128,31 +128,27 @@ static int expander_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, dev);
ret = gpio_initial_status(pdev, &dev_attr_generic_led, GENERIC_LED, 0,
&dev->generic_led_val);
&dev->generic_led_val, false, false);
if (ret)
goto done;
ret = gpio_initial_status(pdev, &dev_attr_pcm_sel, PCM_SEL, 0,
&dev->pcm_sel_val);
&dev->pcm_sel_val, false, false);
if (ret)
goto done;
ret = gpio_initial_status(pdev, &dev_attr_sdio_sel, SDIO_SEL, 0,
&dev->sdio_sel_val);
&dev->sdio_sel_val, false, false);
if (ret)
goto done;
ret = gpio_initial_status(pdev, &dev_attr_tri_led_blu, TRI_LED_BLU, 0,
&dev->tri_led_blu_val);
&dev->tri_led_blu_val , true, true );
if (ret)
goto done;
ret = gpio_initial_status(pdev, &dev_attr_tri_led_red, TRI_LED_RED, 0,
&dev->tri_led_red_val);
&dev->tri_led_red_val , true, true);
if (ret)
goto done;
ret = gpio_initial_status(pdev, &dev_attr_tri_led_grn, TRI_LED_GRN, 0,
&dev->tri_led_grn_val);
if (ret)
goto done;
ret = gpio_initial_status(pdev, &dev_attr_buzzer, BUZZER, 0,
&dev->buzzer_val);
&dev->tri_led_grn_val, true, true);
if (ret)
goto done;
......@@ -169,7 +165,6 @@ static int expander_remove(struct platform_device *pdev)
gpio_final_status(pdev, &dev_attr_tri_led_blu, TRI_LED_BLU, 0);
gpio_final_status(pdev, &dev_attr_tri_led_red, TRI_LED_RED, 0);
gpio_final_status(pdev, &dev_attr_tri_led_grn, TRI_LED_GRN, 0);
gpio_final_status(pdev, &dev_attr_buzzer, BUZZER, 0);
return 0;
}
......
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