162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Driver for the Conexant CX25821 PCIe bridge 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (C) 2009 Conexant Systems Inc. 662306a36Sopenharmony_ci * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com> 762306a36Sopenharmony_ci */ 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci#include <linux/module.h> 1062306a36Sopenharmony_ci#include "cx25821.h" 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ci/********************* GPIO stuffs *********************/ 1362306a36Sopenharmony_civoid cx25821_set_gpiopin_direction(struct cx25821_dev *dev, 1462306a36Sopenharmony_ci int pin_number, int pin_logic_value) 1562306a36Sopenharmony_ci{ 1662306a36Sopenharmony_ci int bit = pin_number; 1762306a36Sopenharmony_ci u32 gpio_oe_reg = GPIO_LO_OE; 1862306a36Sopenharmony_ci u32 gpio_register = 0; 1962306a36Sopenharmony_ci u32 value = 0; 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci /* Check for valid pinNumber */ 2262306a36Sopenharmony_ci if (pin_number >= 47) 2362306a36Sopenharmony_ci return; 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_ci if (pin_number > 31) { 2662306a36Sopenharmony_ci bit = pin_number - 31; 2762306a36Sopenharmony_ci gpio_oe_reg = GPIO_HI_OE; 2862306a36Sopenharmony_ci } 2962306a36Sopenharmony_ci /* Here we will make sure that the GPIOs 0 and 1 are output. keep the 3062306a36Sopenharmony_ci * rest as is */ 3162306a36Sopenharmony_ci gpio_register = cx_read(gpio_oe_reg); 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_ci if (pin_logic_value == 1) 3462306a36Sopenharmony_ci value = gpio_register | Set_GPIO_Bit(bit); 3562306a36Sopenharmony_ci else 3662306a36Sopenharmony_ci value = gpio_register & Clear_GPIO_Bit(bit); 3762306a36Sopenharmony_ci 3862306a36Sopenharmony_ci cx_write(gpio_oe_reg, value); 3962306a36Sopenharmony_ci} 4062306a36Sopenharmony_ciEXPORT_SYMBOL(cx25821_set_gpiopin_direction); 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_cistatic void cx25821_set_gpiopin_logicvalue(struct cx25821_dev *dev, 4362306a36Sopenharmony_ci int pin_number, int pin_logic_value) 4462306a36Sopenharmony_ci{ 4562306a36Sopenharmony_ci int bit = pin_number; 4662306a36Sopenharmony_ci u32 gpio_reg = GPIO_LO; 4762306a36Sopenharmony_ci u32 value = 0; 4862306a36Sopenharmony_ci 4962306a36Sopenharmony_ci /* Check for valid pinNumber */ 5062306a36Sopenharmony_ci if (pin_number >= 47) 5162306a36Sopenharmony_ci return; 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_ci /* change to output direction */ 5462306a36Sopenharmony_ci cx25821_set_gpiopin_direction(dev, pin_number, 0); 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ci if (pin_number > 31) { 5762306a36Sopenharmony_ci bit = pin_number - 31; 5862306a36Sopenharmony_ci gpio_reg = GPIO_HI; 5962306a36Sopenharmony_ci } 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_ci value = cx_read(gpio_reg); 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_ci if (pin_logic_value == 0) 6462306a36Sopenharmony_ci value &= Clear_GPIO_Bit(bit); 6562306a36Sopenharmony_ci else 6662306a36Sopenharmony_ci value |= Set_GPIO_Bit(bit); 6762306a36Sopenharmony_ci 6862306a36Sopenharmony_ci cx_write(gpio_reg, value); 6962306a36Sopenharmony_ci} 7062306a36Sopenharmony_ci 7162306a36Sopenharmony_civoid cx25821_gpio_init(struct cx25821_dev *dev) 7262306a36Sopenharmony_ci{ 7362306a36Sopenharmony_ci if (dev == NULL) 7462306a36Sopenharmony_ci return; 7562306a36Sopenharmony_ci 7662306a36Sopenharmony_ci switch (dev->board) { 7762306a36Sopenharmony_ci case CX25821_BOARD_CONEXANT_ATHENA10: 7862306a36Sopenharmony_ci default: 7962306a36Sopenharmony_ci /* set GPIO 5 to select the path for Medusa/Athena */ 8062306a36Sopenharmony_ci cx25821_set_gpiopin_logicvalue(dev, 5, 1); 8162306a36Sopenharmony_ci msleep(20); 8262306a36Sopenharmony_ci break; 8362306a36Sopenharmony_ci } 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_ci} 86