18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci *  Driver for the Conexant CX25821 PCIe bridge
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci *  Copyright (C) 2009 Conexant Systems Inc.
68c2ecf20Sopenharmony_ci *  Authors  <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
78c2ecf20Sopenharmony_ci */
88c2ecf20Sopenharmony_ci
98c2ecf20Sopenharmony_ci#include <linux/module.h>
108c2ecf20Sopenharmony_ci#include "cx25821.h"
118c2ecf20Sopenharmony_ci
128c2ecf20Sopenharmony_ci/********************* GPIO stuffs *********************/
138c2ecf20Sopenharmony_civoid cx25821_set_gpiopin_direction(struct cx25821_dev *dev,
148c2ecf20Sopenharmony_ci				   int pin_number, int pin_logic_value)
158c2ecf20Sopenharmony_ci{
168c2ecf20Sopenharmony_ci	int bit = pin_number;
178c2ecf20Sopenharmony_ci	u32 gpio_oe_reg = GPIO_LO_OE;
188c2ecf20Sopenharmony_ci	u32 gpio_register = 0;
198c2ecf20Sopenharmony_ci	u32 value = 0;
208c2ecf20Sopenharmony_ci
218c2ecf20Sopenharmony_ci	/* Check for valid pinNumber */
228c2ecf20Sopenharmony_ci	if (pin_number >= 47)
238c2ecf20Sopenharmony_ci		return;
248c2ecf20Sopenharmony_ci
258c2ecf20Sopenharmony_ci	if (pin_number > 31) {
268c2ecf20Sopenharmony_ci		bit = pin_number - 31;
278c2ecf20Sopenharmony_ci		gpio_oe_reg = GPIO_HI_OE;
288c2ecf20Sopenharmony_ci	}
298c2ecf20Sopenharmony_ci	/* Here we will make sure that the GPIOs 0 and 1 are output. keep the
308c2ecf20Sopenharmony_ci	 * rest as is */
318c2ecf20Sopenharmony_ci	gpio_register = cx_read(gpio_oe_reg);
328c2ecf20Sopenharmony_ci
338c2ecf20Sopenharmony_ci	if (pin_logic_value == 1)
348c2ecf20Sopenharmony_ci		value = gpio_register | Set_GPIO_Bit(bit);
358c2ecf20Sopenharmony_ci	else
368c2ecf20Sopenharmony_ci		value = gpio_register & Clear_GPIO_Bit(bit);
378c2ecf20Sopenharmony_ci
388c2ecf20Sopenharmony_ci	cx_write(gpio_oe_reg, value);
398c2ecf20Sopenharmony_ci}
408c2ecf20Sopenharmony_ciEXPORT_SYMBOL(cx25821_set_gpiopin_direction);
418c2ecf20Sopenharmony_ci
428c2ecf20Sopenharmony_cistatic void cx25821_set_gpiopin_logicvalue(struct cx25821_dev *dev,
438c2ecf20Sopenharmony_ci					   int pin_number, int pin_logic_value)
448c2ecf20Sopenharmony_ci{
458c2ecf20Sopenharmony_ci	int bit = pin_number;
468c2ecf20Sopenharmony_ci	u32 gpio_reg = GPIO_LO;
478c2ecf20Sopenharmony_ci	u32 value = 0;
488c2ecf20Sopenharmony_ci
498c2ecf20Sopenharmony_ci	/* Check for valid pinNumber */
508c2ecf20Sopenharmony_ci	if (pin_number >= 47)
518c2ecf20Sopenharmony_ci		return;
528c2ecf20Sopenharmony_ci
538c2ecf20Sopenharmony_ci	/* change to output direction */
548c2ecf20Sopenharmony_ci	cx25821_set_gpiopin_direction(dev, pin_number, 0);
558c2ecf20Sopenharmony_ci
568c2ecf20Sopenharmony_ci	if (pin_number > 31) {
578c2ecf20Sopenharmony_ci		bit = pin_number - 31;
588c2ecf20Sopenharmony_ci		gpio_reg = GPIO_HI;
598c2ecf20Sopenharmony_ci	}
608c2ecf20Sopenharmony_ci
618c2ecf20Sopenharmony_ci	value = cx_read(gpio_reg);
628c2ecf20Sopenharmony_ci
638c2ecf20Sopenharmony_ci	if (pin_logic_value == 0)
648c2ecf20Sopenharmony_ci		value &= Clear_GPIO_Bit(bit);
658c2ecf20Sopenharmony_ci	else
668c2ecf20Sopenharmony_ci		value |= Set_GPIO_Bit(bit);
678c2ecf20Sopenharmony_ci
688c2ecf20Sopenharmony_ci	cx_write(gpio_reg, value);
698c2ecf20Sopenharmony_ci}
708c2ecf20Sopenharmony_ci
718c2ecf20Sopenharmony_civoid cx25821_gpio_init(struct cx25821_dev *dev)
728c2ecf20Sopenharmony_ci{
738c2ecf20Sopenharmony_ci	if (dev == NULL)
748c2ecf20Sopenharmony_ci		return;
758c2ecf20Sopenharmony_ci
768c2ecf20Sopenharmony_ci	switch (dev->board) {
778c2ecf20Sopenharmony_ci	case CX25821_BOARD_CONEXANT_ATHENA10:
788c2ecf20Sopenharmony_ci	default:
798c2ecf20Sopenharmony_ci		/* set GPIO 5 to select the path for Medusa/Athena */
808c2ecf20Sopenharmony_ci		cx25821_set_gpiopin_logicvalue(dev, 5, 1);
818c2ecf20Sopenharmony_ci		msleep(20);
828c2ecf20Sopenharmony_ci		break;
838c2ecf20Sopenharmony_ci	}
848c2ecf20Sopenharmony_ci
858c2ecf20Sopenharmony_ci}
86