1*bebdf98aSRussell King // SPDX-License-Identifier: GPL-2.0 2*bebdf98aSRussell King /* 3*bebdf98aSRussell King * MAX1600 PCMCIA power switch library 4*bebdf98aSRussell King * 5*bebdf98aSRussell King * Copyright (C) 2016 Russell King 6*bebdf98aSRussell King */ 7*bebdf98aSRussell King #include <linux/device.h> 8*bebdf98aSRussell King #include <linux/module.h> 9*bebdf98aSRussell King #include <linux/gpio/consumer.h> 10*bebdf98aSRussell King #include <linux/slab.h> 11*bebdf98aSRussell King #include "max1600.h" 12*bebdf98aSRussell King 13*bebdf98aSRussell King static const char *max1600_gpio_name[2][MAX1600_GPIO_MAX] = { 14*bebdf98aSRussell King { "a0vcc", "a1vcc", "a0vpp", "a1vpp" }, 15*bebdf98aSRussell King { "b0vcc", "b1vcc", "b0vpp", "b1vpp" }, 16*bebdf98aSRussell King }; 17*bebdf98aSRussell King 18*bebdf98aSRussell King int max1600_init(struct device *dev, struct max1600 **ptr, 19*bebdf98aSRussell King unsigned int channel, unsigned int code) 20*bebdf98aSRussell King { 21*bebdf98aSRussell King struct max1600 *m; 22*bebdf98aSRussell King int chan; 23*bebdf98aSRussell King int i; 24*bebdf98aSRussell King 25*bebdf98aSRussell King switch (channel) { 26*bebdf98aSRussell King case MAX1600_CHAN_A: 27*bebdf98aSRussell King chan = 0; 28*bebdf98aSRussell King break; 29*bebdf98aSRussell King case MAX1600_CHAN_B: 30*bebdf98aSRussell King chan = 1; 31*bebdf98aSRussell King break; 32*bebdf98aSRussell King default: 33*bebdf98aSRussell King return -EINVAL; 34*bebdf98aSRussell King } 35*bebdf98aSRussell King 36*bebdf98aSRussell King if (code != MAX1600_CODE_LOW && code != MAX1600_CODE_HIGH) 37*bebdf98aSRussell King return -EINVAL; 38*bebdf98aSRussell King 39*bebdf98aSRussell King m = devm_kzalloc(dev, sizeof(*m), GFP_KERNEL); 40*bebdf98aSRussell King if (!m) 41*bebdf98aSRussell King return -ENOMEM; 42*bebdf98aSRussell King 43*bebdf98aSRussell King m->dev = dev; 44*bebdf98aSRussell King m->code = code; 45*bebdf98aSRussell King 46*bebdf98aSRussell King for (i = 0; i < MAX1600_GPIO_MAX; i++) { 47*bebdf98aSRussell King const char *name; 48*bebdf98aSRussell King 49*bebdf98aSRussell King name = max1600_gpio_name[chan][i]; 50*bebdf98aSRussell King if (i != MAX1600_GPIO_0VPP) { 51*bebdf98aSRussell King m->gpio[i] = devm_gpiod_get(dev, name, GPIOD_OUT_LOW); 52*bebdf98aSRussell King } else { 53*bebdf98aSRussell King m->gpio[i] = devm_gpiod_get_optional(dev, name, 54*bebdf98aSRussell King GPIOD_OUT_LOW); 55*bebdf98aSRussell King if (!m->gpio[i]) 56*bebdf98aSRussell King break; 57*bebdf98aSRussell King } 58*bebdf98aSRussell King if (IS_ERR(m->gpio[i])) 59*bebdf98aSRussell King return PTR_ERR(m->gpio[i]); 60*bebdf98aSRussell King } 61*bebdf98aSRussell King 62*bebdf98aSRussell King *ptr = m; 63*bebdf98aSRussell King 64*bebdf98aSRussell King return 0; 65*bebdf98aSRussell King } 66*bebdf98aSRussell King EXPORT_SYMBOL_GPL(max1600_init); 67*bebdf98aSRussell King 68*bebdf98aSRussell King int max1600_configure(struct max1600 *m, unsigned int vcc, unsigned int vpp) 69*bebdf98aSRussell King { 70*bebdf98aSRussell King DECLARE_BITMAP(values, MAX1600_GPIO_MAX) = { 0, }; 71*bebdf98aSRussell King int n = MAX1600_GPIO_0VPP; 72*bebdf98aSRussell King 73*bebdf98aSRussell King if (m->gpio[MAX1600_GPIO_0VPP]) { 74*bebdf98aSRussell King if (vpp == 0) { 75*bebdf98aSRussell King __assign_bit(MAX1600_GPIO_0VPP, values, 0); 76*bebdf98aSRussell King __assign_bit(MAX1600_GPIO_1VPP, values, 0); 77*bebdf98aSRussell King } else if (vpp == 120) { 78*bebdf98aSRussell King __assign_bit(MAX1600_GPIO_0VPP, values, 0); 79*bebdf98aSRussell King __assign_bit(MAX1600_GPIO_1VPP, values, 1); 80*bebdf98aSRussell King } else if (vpp == vcc) { 81*bebdf98aSRussell King __assign_bit(MAX1600_GPIO_0VPP, values, 1); 82*bebdf98aSRussell King __assign_bit(MAX1600_GPIO_1VPP, values, 0); 83*bebdf98aSRussell King } else { 84*bebdf98aSRussell King dev_err(m->dev, "unrecognised Vpp %u.%uV\n", 85*bebdf98aSRussell King vpp / 10, vpp % 10); 86*bebdf98aSRussell King return -EINVAL; 87*bebdf98aSRussell King } 88*bebdf98aSRussell King n = MAX1600_GPIO_MAX; 89*bebdf98aSRussell King } else if (vpp != vcc && vpp != 0) { 90*bebdf98aSRussell King dev_err(m->dev, "no VPP control\n"); 91*bebdf98aSRussell King return -EINVAL; 92*bebdf98aSRussell King } 93*bebdf98aSRussell King 94*bebdf98aSRussell King if (vcc == 0) { 95*bebdf98aSRussell King __assign_bit(MAX1600_GPIO_0VCC, values, 0); 96*bebdf98aSRussell King __assign_bit(MAX1600_GPIO_1VCC, values, 0); 97*bebdf98aSRussell King } else if (vcc == 33) { /* VY */ 98*bebdf98aSRussell King __assign_bit(MAX1600_GPIO_0VCC, values, 1); 99*bebdf98aSRussell King __assign_bit(MAX1600_GPIO_1VCC, values, 0); 100*bebdf98aSRussell King } else if (vcc == 50) { /* VX */ 101*bebdf98aSRussell King __assign_bit(MAX1600_GPIO_0VCC, values, 0); 102*bebdf98aSRussell King __assign_bit(MAX1600_GPIO_1VCC, values, 1); 103*bebdf98aSRussell King } else { 104*bebdf98aSRussell King dev_err(m->dev, "unrecognised Vcc %u.%uV\n", 105*bebdf98aSRussell King vcc / 10, vcc % 10); 106*bebdf98aSRussell King return -EINVAL; 107*bebdf98aSRussell King } 108*bebdf98aSRussell King 109*bebdf98aSRussell King if (m->code == MAX1600_CODE_HIGH) { 110*bebdf98aSRussell King /* 111*bebdf98aSRussell King * Cirrus mode appears to be the same as Intel mode, 112*bebdf98aSRussell King * except the VCC pins are inverted. 113*bebdf98aSRussell King */ 114*bebdf98aSRussell King __change_bit(MAX1600_GPIO_0VCC, values); 115*bebdf98aSRussell King __change_bit(MAX1600_GPIO_1VCC, values); 116*bebdf98aSRussell King } 117*bebdf98aSRussell King 118*bebdf98aSRussell King return gpiod_set_array_value_cansleep(n, m->gpio, NULL, values); 119*bebdf98aSRussell King } 120*bebdf98aSRussell King EXPORT_SYMBOL_GPL(max1600_configure); 121*bebdf98aSRussell King 122*bebdf98aSRussell King MODULE_LICENSE("GPL v2"); 123