[829f35]: drivers / i2c / busses / i2c-gpio-of.c Maximize Restore History

Download this file

i2c-gpio-of.c    151 lines (124 with data), 3.6 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
/*
* drivers/i2c/busses/i2c-gpio-of.c
*
* GPIO-based bitbanging I2C driver with OF bindings
* Copyright (C) 2009 Albert Herranz
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include "i2c-gpio-common.h"
#include <linux/of_platform.h>
#include <linux/of_i2c.h>
#include <linux/of_gpio.h>
#include <linux/i2c-algo-bit.h>
#include <linux/init.h>
#include <linux/module.h>
#define DRV_MODULE_NAME "i2c-gpio-of"
#define DRV_DESCRIPTION "GPIO-based bitbanging I2C driver with OF bindings"
#define DRV_AUTHOR "Albert Herranz"
#define drv_printk(level, format, arg...) \
printk(level DRV_MODULE_NAME ": " format , ## arg)
/*
* OF platform bindings.
*
*/
static int __devinit i2c_gpio_of_probe(struct of_device *odev,
const struct of_device_id *match)
{
struct i2c_gpio_platform_data *pdata;
struct i2c_adapter *adap;
const unsigned long *prop;
int sda_pin, scl_pin;
int error = -ENOMEM;
pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
if (!pdata)
goto err_alloc_pdata;
adap = kzalloc(sizeof(*adap), GFP_KERNEL);
if (!adap)
goto err_alloc_adap;
sda_pin = of_get_gpio(odev->node, 0);
scl_pin = of_get_gpio(odev->node, 1);
if (sda_pin < 0 || scl_pin < 0) {
error = -EINVAL;
pr_err("%s: invalid GPIO pins, sda=%d/scl=%d\n",
odev->node->full_name, sda_pin, scl_pin);
goto err_gpio_pin;
}
pdata->sda_pin = sda_pin;
pdata->scl_pin = scl_pin;
prop = of_get_property(odev->node, "sda-is-open-drain", NULL);
if (prop)
pdata->sda_is_open_drain = *prop;
prop = of_get_property(odev->node, "scl-is-open-drain", NULL);
if (prop)
pdata->scl_is_open_drain = *prop;
prop = of_get_property(odev->node, "scl-is-output-only", NULL);
if (prop)
pdata->scl_is_output_only = *prop;
prop = of_get_property(odev->node, "udelay", NULL);
if (prop)
pdata->udelay = *prop;
prop = of_get_property(odev->node, "timeout", NULL);
if (prop)
pdata->timeout = msecs_to_jiffies(*prop);
error = i2c_gpio_adapter_probe(adap, pdata, &odev->dev,
odev->node->node, THIS_MODULE);
if (error)
goto err_probe;
dev_set_drvdata(&odev->dev, adap);
of_register_i2c_devices(adap, odev->node);
return 0;
err_probe:
err_gpio_pin:
kfree(adap);
err_alloc_adap:
kfree(pdata);
err_alloc_pdata:
return error;
};
static int __devexit i2c_gpio_of_remove(struct of_device *odev)
{
struct i2c_gpio_platform_data *pdata;
struct i2c_adapter *adap;
struct i2c_algo_bit_data *bit_data;
adap = dev_get_drvdata(&odev->dev);
bit_data = adap->algo_data;
pdata = bit_data->data;
i2c_gpio_adapter_remove(adap, pdata);
kfree(pdata);
kfree(adap);
return 0;
};
static const struct of_device_id i2c_gpio_of_match[] = {
{.compatible = "virtual,i2c-gpio",},
{},
};
MODULE_DEVICE_TABLE(of, i2c_gpio_of_match);
static struct of_platform_driver i2c_gpio_of_driver = {
.match_table = i2c_gpio_of_match,
.probe = i2c_gpio_of_probe,
.remove = __devexit_p(i2c_gpio_of_remove),
.driver = {
.owner = THIS_MODULE,
.name = DRV_MODULE_NAME,
},
};
static int __init i2c_gpio_of_init(void)
{
int error;
error = of_register_platform_driver(&i2c_gpio_of_driver);
if (error)
drv_printk(KERN_ERR, "OF registration failed (%d)\n", error);
return error;
}
static void __exit i2c_gpio_of_exit(void)
{
of_unregister_platform_driver(&i2c_gpio_of_driver);
}
module_init(i2c_gpio_of_init);
module_exit(i2c_gpio_of_exit);
MODULE_DESCRIPTION(DRV_DESCRIPTION);
MODULE_AUTHOR(DRV_AUTHOR);
MODULE_LICENSE("GPL");