0001
0002
0003
0004
0005
0006
0007 #include <linux/device.h>
0008 #include <linux/module.h>
0009 #include <linux/gpio/consumer.h>
0010 #include <linux/slab.h>
0011 #include "max1600.h"
0012
0013 static const char *max1600_gpio_name[2][MAX1600_GPIO_MAX] = {
0014 { "a0vcc", "a1vcc", "a0vpp", "a1vpp" },
0015 { "b0vcc", "b1vcc", "b0vpp", "b1vpp" },
0016 };
0017
0018 int max1600_init(struct device *dev, struct max1600 **ptr,
0019 unsigned int channel, unsigned int code)
0020 {
0021 struct max1600 *m;
0022 int chan;
0023 int i;
0024
0025 switch (channel) {
0026 case MAX1600_CHAN_A:
0027 chan = 0;
0028 break;
0029 case MAX1600_CHAN_B:
0030 chan = 1;
0031 break;
0032 default:
0033 return -EINVAL;
0034 }
0035
0036 if (code != MAX1600_CODE_LOW && code != MAX1600_CODE_HIGH)
0037 return -EINVAL;
0038
0039 m = devm_kzalloc(dev, sizeof(*m), GFP_KERNEL);
0040 if (!m)
0041 return -ENOMEM;
0042
0043 m->dev = dev;
0044 m->code = code;
0045
0046 for (i = 0; i < MAX1600_GPIO_MAX; i++) {
0047 const char *name;
0048
0049 name = max1600_gpio_name[chan][i];
0050 if (i != MAX1600_GPIO_0VPP) {
0051 m->gpio[i] = devm_gpiod_get(dev, name, GPIOD_OUT_LOW);
0052 } else {
0053 m->gpio[i] = devm_gpiod_get_optional(dev, name,
0054 GPIOD_OUT_LOW);
0055 if (!m->gpio[i])
0056 break;
0057 }
0058 if (IS_ERR(m->gpio[i]))
0059 return PTR_ERR(m->gpio[i]);
0060 }
0061
0062 *ptr = m;
0063
0064 return 0;
0065 }
0066 EXPORT_SYMBOL_GPL(max1600_init);
0067
0068 int max1600_configure(struct max1600 *m, unsigned int vcc, unsigned int vpp)
0069 {
0070 DECLARE_BITMAP(values, MAX1600_GPIO_MAX) = { 0, };
0071 int n = MAX1600_GPIO_0VPP;
0072
0073 if (m->gpio[MAX1600_GPIO_0VPP]) {
0074 if (vpp == 0) {
0075 __assign_bit(MAX1600_GPIO_0VPP, values, 0);
0076 __assign_bit(MAX1600_GPIO_1VPP, values, 0);
0077 } else if (vpp == 120) {
0078 __assign_bit(MAX1600_GPIO_0VPP, values, 0);
0079 __assign_bit(MAX1600_GPIO_1VPP, values, 1);
0080 } else if (vpp == vcc) {
0081 __assign_bit(MAX1600_GPIO_0VPP, values, 1);
0082 __assign_bit(MAX1600_GPIO_1VPP, values, 0);
0083 } else {
0084 dev_err(m->dev, "unrecognised Vpp %u.%uV\n",
0085 vpp / 10, vpp % 10);
0086 return -EINVAL;
0087 }
0088 n = MAX1600_GPIO_MAX;
0089 } else if (vpp != vcc && vpp != 0) {
0090 dev_err(m->dev, "no VPP control\n");
0091 return -EINVAL;
0092 }
0093
0094 if (vcc == 0) {
0095 __assign_bit(MAX1600_GPIO_0VCC, values, 0);
0096 __assign_bit(MAX1600_GPIO_1VCC, values, 0);
0097 } else if (vcc == 33) {
0098 __assign_bit(MAX1600_GPIO_0VCC, values, 1);
0099 __assign_bit(MAX1600_GPIO_1VCC, values, 0);
0100 } else if (vcc == 50) {
0101 __assign_bit(MAX1600_GPIO_0VCC, values, 0);
0102 __assign_bit(MAX1600_GPIO_1VCC, values, 1);
0103 } else {
0104 dev_err(m->dev, "unrecognised Vcc %u.%uV\n",
0105 vcc / 10, vcc % 10);
0106 return -EINVAL;
0107 }
0108
0109 if (m->code == MAX1600_CODE_HIGH) {
0110
0111
0112
0113
0114 __change_bit(MAX1600_GPIO_0VCC, values);
0115 __change_bit(MAX1600_GPIO_1VCC, values);
0116 }
0117
0118 return gpiod_set_array_value_cansleep(n, m->gpio, NULL, values);
0119 }
0120 EXPORT_SYMBOL_GPL(max1600_configure);
0121
0122 MODULE_LICENSE("GPL v2");