162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 262306a36Sopenharmony_ci/* NXP PCF50633 GPIO Driver 362306a36Sopenharmony_ci * 462306a36Sopenharmony_ci * (C) 2006-2008 by Openmoko, Inc. 562306a36Sopenharmony_ci * Author: Balaji Rao <balajirrao@openmoko.org> 662306a36Sopenharmony_ci * All rights reserved. 762306a36Sopenharmony_ci * 862306a36Sopenharmony_ci * Broken down from monstrous PCF50633 driver mainly by 962306a36Sopenharmony_ci * Harald Welte, Andy Green and Werner Almesberger 1062306a36Sopenharmony_ci */ 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ci#include <linux/kernel.h> 1362306a36Sopenharmony_ci#include <linux/module.h> 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_ci#include <linux/mfd/pcf50633/core.h> 1662306a36Sopenharmony_ci#include <linux/mfd/pcf50633/gpio.h> 1762306a36Sopenharmony_ci#include <linux/mfd/pcf50633/pmic.h> 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_cistatic const u8 pcf50633_regulator_registers[PCF50633_NUM_REGULATORS] = { 2062306a36Sopenharmony_ci [PCF50633_REGULATOR_AUTO] = PCF50633_REG_AUTOOUT, 2162306a36Sopenharmony_ci [PCF50633_REGULATOR_DOWN1] = PCF50633_REG_DOWN1OUT, 2262306a36Sopenharmony_ci [PCF50633_REGULATOR_DOWN2] = PCF50633_REG_DOWN2OUT, 2362306a36Sopenharmony_ci [PCF50633_REGULATOR_MEMLDO] = PCF50633_REG_MEMLDOOUT, 2462306a36Sopenharmony_ci [PCF50633_REGULATOR_LDO1] = PCF50633_REG_LDO1OUT, 2562306a36Sopenharmony_ci [PCF50633_REGULATOR_LDO2] = PCF50633_REG_LDO2OUT, 2662306a36Sopenharmony_ci [PCF50633_REGULATOR_LDO3] = PCF50633_REG_LDO3OUT, 2762306a36Sopenharmony_ci [PCF50633_REGULATOR_LDO4] = PCF50633_REG_LDO4OUT, 2862306a36Sopenharmony_ci [PCF50633_REGULATOR_LDO5] = PCF50633_REG_LDO5OUT, 2962306a36Sopenharmony_ci [PCF50633_REGULATOR_LDO6] = PCF50633_REG_LDO6OUT, 3062306a36Sopenharmony_ci [PCF50633_REGULATOR_HCLDO] = PCF50633_REG_HCLDOOUT, 3162306a36Sopenharmony_ci}; 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_ciint pcf50633_gpio_set(struct pcf50633 *pcf, int gpio, u8 val) 3462306a36Sopenharmony_ci{ 3562306a36Sopenharmony_ci u8 reg; 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_ci reg = gpio - PCF50633_GPIO1 + PCF50633_REG_GPIO1CFG; 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_ci return pcf50633_reg_set_bit_mask(pcf, reg, 0x07, val); 4062306a36Sopenharmony_ci} 4162306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(pcf50633_gpio_set); 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_ciu8 pcf50633_gpio_get(struct pcf50633 *pcf, int gpio) 4462306a36Sopenharmony_ci{ 4562306a36Sopenharmony_ci u8 reg, val; 4662306a36Sopenharmony_ci 4762306a36Sopenharmony_ci reg = gpio - PCF50633_GPIO1 + PCF50633_REG_GPIO1CFG; 4862306a36Sopenharmony_ci val = pcf50633_reg_read(pcf, reg) & 0x07; 4962306a36Sopenharmony_ci 5062306a36Sopenharmony_ci return val; 5162306a36Sopenharmony_ci} 5262306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(pcf50633_gpio_get); 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_ciint pcf50633_gpio_invert_set(struct pcf50633 *pcf, int gpio, int invert) 5562306a36Sopenharmony_ci{ 5662306a36Sopenharmony_ci u8 val, reg; 5762306a36Sopenharmony_ci 5862306a36Sopenharmony_ci reg = gpio - PCF50633_GPIO1 + PCF50633_REG_GPIO1CFG; 5962306a36Sopenharmony_ci val = !!invert << 3; 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_ci return pcf50633_reg_set_bit_mask(pcf, reg, 1 << 3, val); 6262306a36Sopenharmony_ci} 6362306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(pcf50633_gpio_invert_set); 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_ciint pcf50633_gpio_invert_get(struct pcf50633 *pcf, int gpio) 6662306a36Sopenharmony_ci{ 6762306a36Sopenharmony_ci u8 reg, val; 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_ci reg = gpio - PCF50633_GPIO1 + PCF50633_REG_GPIO1CFG; 7062306a36Sopenharmony_ci val = pcf50633_reg_read(pcf, reg); 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_ci return val & (1 << 3); 7362306a36Sopenharmony_ci} 7462306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(pcf50633_gpio_invert_get); 7562306a36Sopenharmony_ci 7662306a36Sopenharmony_ciint pcf50633_gpio_power_supply_set(struct pcf50633 *pcf, 7762306a36Sopenharmony_ci int gpio, int regulator, int on) 7862306a36Sopenharmony_ci{ 7962306a36Sopenharmony_ci u8 reg, val, mask; 8062306a36Sopenharmony_ci 8162306a36Sopenharmony_ci /* the *ENA register is always one after the *OUT register */ 8262306a36Sopenharmony_ci reg = pcf50633_regulator_registers[regulator] + 1; 8362306a36Sopenharmony_ci 8462306a36Sopenharmony_ci val = !!on << (gpio - PCF50633_GPIO1); 8562306a36Sopenharmony_ci mask = 1 << (gpio - PCF50633_GPIO1); 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_ci return pcf50633_reg_set_bit_mask(pcf, reg, mask, val); 8862306a36Sopenharmony_ci} 8962306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(pcf50633_gpio_power_supply_set); 9062306a36Sopenharmony_ci 9162306a36Sopenharmony_ciMODULE_LICENSE("GPL"); 92