1 // SPDX-License-Identifier: GPL-2.0
3 * MAX1600 PCMCIA power switch library
5 * Copyright (C) 2016 Russell King
7 #include <linux/device.h>
8 #include <linux/module.h>
9 #include <linux/gpio/consumer.h>
10 #include <linux/slab.h>
13 static const char *max1600_gpio_name
[2][MAX1600_GPIO_MAX
] = {
14 { "a0vcc", "a1vcc", "a0vpp", "a1vpp" },
15 { "b0vcc", "b1vcc", "b0vpp", "b1vpp" },
18 int max1600_init(struct device
*dev
, struct max1600
**ptr
,
19 unsigned int channel
, unsigned int code
)
36 if (code
!= MAX1600_CODE_LOW
&& code
!= MAX1600_CODE_HIGH
)
39 m
= devm_kzalloc(dev
, sizeof(*m
), GFP_KERNEL
);
46 for (i
= 0; i
< MAX1600_GPIO_MAX
; i
++) {
49 name
= max1600_gpio_name
[chan
][i
];
50 if (i
!= MAX1600_GPIO_0VPP
) {
51 m
->gpio
[i
] = devm_gpiod_get(dev
, name
, GPIOD_OUT_LOW
);
53 m
->gpio
[i
] = devm_gpiod_get_optional(dev
, name
,
58 if (IS_ERR(m
->gpio
[i
]))
59 return PTR_ERR(m
->gpio
[i
]);
66 EXPORT_SYMBOL_GPL(max1600_init
);
68 int max1600_configure(struct max1600
*m
, unsigned int vcc
, unsigned int vpp
)
70 DECLARE_BITMAP(values
, MAX1600_GPIO_MAX
) = { 0, };
71 int n
= MAX1600_GPIO_0VPP
;
73 if (m
->gpio
[MAX1600_GPIO_0VPP
]) {
75 __assign_bit(MAX1600_GPIO_0VPP
, values
, 0);
76 __assign_bit(MAX1600_GPIO_1VPP
, values
, 0);
77 } else if (vpp
== 120) {
78 __assign_bit(MAX1600_GPIO_0VPP
, values
, 0);
79 __assign_bit(MAX1600_GPIO_1VPP
, values
, 1);
80 } else if (vpp
== vcc
) {
81 __assign_bit(MAX1600_GPIO_0VPP
, values
, 1);
82 __assign_bit(MAX1600_GPIO_1VPP
, values
, 0);
84 dev_err(m
->dev
, "unrecognised Vpp %u.%uV\n",
89 } else if (vpp
!= vcc
&& vpp
!= 0) {
90 dev_err(m
->dev
, "no VPP control\n");
95 __assign_bit(MAX1600_GPIO_0VCC
, values
, 0);
96 __assign_bit(MAX1600_GPIO_1VCC
, values
, 0);
97 } else if (vcc
== 33) { /* VY */
98 __assign_bit(MAX1600_GPIO_0VCC
, values
, 1);
99 __assign_bit(MAX1600_GPIO_1VCC
, values
, 0);
100 } else if (vcc
== 50) { /* VX */
101 __assign_bit(MAX1600_GPIO_0VCC
, values
, 0);
102 __assign_bit(MAX1600_GPIO_1VCC
, values
, 1);
104 dev_err(m
->dev
, "unrecognised Vcc %u.%uV\n",
109 if (m
->code
== MAX1600_CODE_HIGH
) {
111 * Cirrus mode appears to be the same as Intel mode,
112 * except the VCC pins are inverted.
114 __change_bit(MAX1600_GPIO_0VCC
, values
);
115 __change_bit(MAX1600_GPIO_1VCC
, values
);
118 return gpiod_set_array_value_cansleep(n
, m
->gpio
, NULL
, values
);
120 EXPORT_SYMBOL_GPL(max1600_configure
);
122 MODULE_LICENSE("GPL v2");