1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | /* NXP PCF50633 GPIO Driver |
3 | * |
4 | * (C) 2006-2008 by Openmoko, Inc. |
5 | * Author: Balaji Rao <balajirrao@openmoko.org> |
6 | * All rights reserved. |
7 | * |
8 | * Broken down from monstrous PCF50633 driver mainly by |
9 | * Harald Welte, Andy Green and Werner Almesberger |
10 | */ |
11 | |
12 | #include <linux/kernel.h> |
13 | #include <linux/module.h> |
14 | |
15 | #include <linux/mfd/pcf50633/core.h> |
16 | #include <linux/mfd/pcf50633/gpio.h> |
17 | #include <linux/mfd/pcf50633/pmic.h> |
18 | |
19 | static const u8 pcf50633_regulator_registers[PCF50633_NUM_REGULATORS] = { |
20 | [PCF50633_REGULATOR_AUTO] = PCF50633_REG_AUTOOUT, |
21 | [PCF50633_REGULATOR_DOWN1] = PCF50633_REG_DOWN1OUT, |
22 | [PCF50633_REGULATOR_DOWN2] = PCF50633_REG_DOWN2OUT, |
23 | [PCF50633_REGULATOR_MEMLDO] = PCF50633_REG_MEMLDOOUT, |
24 | [PCF50633_REGULATOR_LDO1] = PCF50633_REG_LDO1OUT, |
25 | [PCF50633_REGULATOR_LDO2] = PCF50633_REG_LDO2OUT, |
26 | [PCF50633_REGULATOR_LDO3] = PCF50633_REG_LDO3OUT, |
27 | [PCF50633_REGULATOR_LDO4] = PCF50633_REG_LDO4OUT, |
28 | [PCF50633_REGULATOR_LDO5] = PCF50633_REG_LDO5OUT, |
29 | [PCF50633_REGULATOR_LDO6] = PCF50633_REG_LDO6OUT, |
30 | [PCF50633_REGULATOR_HCLDO] = PCF50633_REG_HCLDOOUT, |
31 | }; |
32 | |
33 | int pcf50633_gpio_set(struct pcf50633 *pcf, int gpio, u8 val) |
34 | { |
35 | u8 reg; |
36 | |
37 | reg = gpio - PCF50633_GPIO1 + PCF50633_REG_GPIO1CFG; |
38 | |
39 | return pcf50633_reg_set_bit_mask(pcf, reg, mask: 0x07, val); |
40 | } |
41 | EXPORT_SYMBOL_GPL(pcf50633_gpio_set); |
42 | |
43 | u8 pcf50633_gpio_get(struct pcf50633 *pcf, int gpio) |
44 | { |
45 | u8 reg, val; |
46 | |
47 | reg = gpio - PCF50633_GPIO1 + PCF50633_REG_GPIO1CFG; |
48 | val = pcf50633_reg_read(pcf, reg) & 0x07; |
49 | |
50 | return val; |
51 | } |
52 | EXPORT_SYMBOL_GPL(pcf50633_gpio_get); |
53 | |
54 | int pcf50633_gpio_invert_set(struct pcf50633 *pcf, int gpio, int invert) |
55 | { |
56 | u8 val, reg; |
57 | |
58 | reg = gpio - PCF50633_GPIO1 + PCF50633_REG_GPIO1CFG; |
59 | val = !!invert << 3; |
60 | |
61 | return pcf50633_reg_set_bit_mask(pcf, reg, mask: 1 << 3, val); |
62 | } |
63 | EXPORT_SYMBOL_GPL(pcf50633_gpio_invert_set); |
64 | |
65 | int pcf50633_gpio_invert_get(struct pcf50633 *pcf, int gpio) |
66 | { |
67 | u8 reg, val; |
68 | |
69 | reg = gpio - PCF50633_GPIO1 + PCF50633_REG_GPIO1CFG; |
70 | val = pcf50633_reg_read(pcf, reg); |
71 | |
72 | return val & (1 << 3); |
73 | } |
74 | EXPORT_SYMBOL_GPL(pcf50633_gpio_invert_get); |
75 | |
76 | int pcf50633_gpio_power_supply_set(struct pcf50633 *pcf, |
77 | int gpio, int regulator, int on) |
78 | { |
79 | u8 reg, val, mask; |
80 | |
81 | /* the *ENA register is always one after the *OUT register */ |
82 | reg = pcf50633_regulator_registers[regulator] + 1; |
83 | |
84 | val = !!on << (gpio - PCF50633_GPIO1); |
85 | mask = 1 << (gpio - PCF50633_GPIO1); |
86 | |
87 | return pcf50633_reg_set_bit_mask(pcf, reg, mask, val); |
88 | } |
89 | EXPORT_SYMBOL_GPL(pcf50633_gpio_power_supply_set); |
90 | |
91 | MODULE_LICENSE("GPL" ); |
92 | |