0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #include <linux/module.h>
0015 #include <linux/kernel.h>
0016 #include <linux/delay.h>
0017 #include <linux/device.h>
0018 #include <linux/gpio.h>
0019
0020 #include <sound/l3.h>
0021
0022
0023
0024
0025
0026 static void sendbyte(struct l3_pins *adap, unsigned int byte)
0027 {
0028 int i;
0029
0030 for (i = 0; i < 8; i++) {
0031 adap->setclk(adap, 0);
0032 udelay(adap->data_hold);
0033 adap->setdat(adap, byte & 1);
0034 udelay(adap->data_setup);
0035 adap->setclk(adap, 1);
0036 udelay(adap->clock_high);
0037 byte >>= 1;
0038 }
0039 }
0040
0041
0042
0043
0044
0045
0046 static void sendbytes(struct l3_pins *adap, const u8 *buf,
0047 int len)
0048 {
0049 int i;
0050
0051 for (i = 0; i < len; i++) {
0052 if (i) {
0053 udelay(adap->mode_hold);
0054 adap->setmode(adap, 0);
0055 udelay(adap->mode);
0056 }
0057 adap->setmode(adap, 1);
0058 udelay(adap->mode_setup);
0059 sendbyte(adap, buf[i]);
0060 }
0061 }
0062
0063 int l3_write(struct l3_pins *adap, u8 addr, u8 *data, int len)
0064 {
0065 adap->setclk(adap, 1);
0066 adap->setdat(adap, 1);
0067 adap->setmode(adap, 1);
0068 udelay(adap->mode);
0069
0070 adap->setmode(adap, 0);
0071 udelay(adap->mode_setup);
0072 sendbyte(adap, addr);
0073 udelay(adap->mode_hold);
0074
0075 sendbytes(adap, data, len);
0076
0077 adap->setclk(adap, 1);
0078 adap->setdat(adap, 1);
0079 adap->setmode(adap, 0);
0080
0081 return len;
0082 }
0083 EXPORT_SYMBOL_GPL(l3_write);
0084
0085
0086 static void l3_set_clk(struct l3_pins *adap, int val)
0087 {
0088 gpio_set_value(adap->gpio_clk, val);
0089 }
0090
0091 static void l3_set_data(struct l3_pins *adap, int val)
0092 {
0093 gpio_set_value(adap->gpio_data, val);
0094 }
0095
0096 static void l3_set_mode(struct l3_pins *adap, int val)
0097 {
0098 gpio_set_value(adap->gpio_mode, val);
0099 }
0100
0101 int l3_set_gpio_ops(struct device *dev, struct l3_pins *adap)
0102 {
0103 int ret;
0104
0105 if (!adap->use_gpios)
0106 return -EINVAL;
0107
0108 ret = devm_gpio_request_one(dev, adap->gpio_data,
0109 GPIOF_OUT_INIT_LOW, "l3_data");
0110 if (ret < 0)
0111 return ret;
0112 adap->setdat = l3_set_data;
0113
0114 ret = devm_gpio_request_one(dev, adap->gpio_clk,
0115 GPIOF_OUT_INIT_LOW, "l3_clk");
0116 if (ret < 0)
0117 return ret;
0118 adap->setclk = l3_set_clk;
0119
0120 ret = devm_gpio_request_one(dev, adap->gpio_mode,
0121 GPIOF_OUT_INIT_LOW, "l3_mode");
0122 if (ret < 0)
0123 return ret;
0124 adap->setmode = l3_set_mode;
0125
0126 return 0;
0127 }
0128 EXPORT_SYMBOL_GPL(l3_set_gpio_ops);
0129
0130 MODULE_DESCRIPTION("L3 bit-banging driver");
0131 MODULE_AUTHOR("Christian Pellegrin <chripell@evolware.org>");
0132 MODULE_LICENSE("GPL");