118056f34SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0
218056f34SGreg Kroah-Hartman /*
33d461c91SSean MacLennan  * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
43d461c91SSean MacLennan  *
53d461c91SSean MacLennan  * Based on the r8180 driver, which is:
6559a4c31SAndrea Merello  * Copyright 2004-2005 Andrea Merello <andrea.merello@gmail.com>, et al.
73d461c91SSean MacLennan  *
818056f34SGreg Kroah-Hartman  * Contact Information: wlanfae <wlanfae@realtek.com>
918056f34SGreg Kroah-Hartman  */
103d461c91SSean MacLennan #include "rtl_core.h"
113d461c91SSean MacLennan #include "rtl_eeprom.h"
123d461c91SSean MacLennan 
_rtl92e_gpio_write_bit(struct net_device * dev,int no,bool val)1308582d83SMateusz Kulikowski static void _rtl92e_gpio_write_bit(struct net_device *dev, int no, bool val)
143d461c91SSean MacLennan {
1508582d83SMateusz Kulikowski 	u8 reg = rtl92e_readb(dev, EPROM_CMD);
1608582d83SMateusz Kulikowski 
1708582d83SMateusz Kulikowski 	if (val)
1808582d83SMateusz Kulikowski 		reg |= 1 << no;
193d461c91SSean MacLennan 	else
2008582d83SMateusz Kulikowski 		reg &= ~(1 << no);
213d461c91SSean MacLennan 
2208582d83SMateusz Kulikowski 	rtl92e_writeb(dev, EPROM_CMD, reg);
233d461c91SSean MacLennan 	udelay(EPROM_DELAY);
243d461c91SSean MacLennan }
253d461c91SSean MacLennan 
_rtl92e_gpio_get_bit(struct net_device * dev,int no)2608582d83SMateusz Kulikowski static bool _rtl92e_gpio_get_bit(struct net_device *dev, int no)
273d461c91SSean MacLennan {
2808582d83SMateusz Kulikowski 	u8 reg = rtl92e_readb(dev, EPROM_CMD);
2908582d83SMateusz Kulikowski 
3008582d83SMateusz Kulikowski 	return (reg >> no) & 0x1;
313d461c91SSean MacLennan }
323d461c91SSean MacLennan 
_rtl92e_eeprom_ck_cycle(struct net_device * dev)3308582d83SMateusz Kulikowski static void _rtl92e_eeprom_ck_cycle(struct net_device *dev)
343d461c91SSean MacLennan {
3508582d83SMateusz Kulikowski 	_rtl92e_gpio_write_bit(dev, EPROM_CK_BIT, 1);
3608582d83SMateusz Kulikowski 	_rtl92e_gpio_write_bit(dev, EPROM_CK_BIT, 0);
373d461c91SSean MacLennan }
383d461c91SSean MacLennan 
_rtl92e_eeprom_xfer(struct net_device * dev,u16 data,int tx_len)3908582d83SMateusz Kulikowski static u16 _rtl92e_eeprom_xfer(struct net_device *dev, u16 data, int tx_len)
403d461c91SSean MacLennan {
4108582d83SMateusz Kulikowski 	u16 ret = 0;
4208582d83SMateusz Kulikowski 	int rx_len = 16;
433d461c91SSean MacLennan 
4408582d83SMateusz Kulikowski 	_rtl92e_gpio_write_bit(dev, EPROM_CS_BIT, 1);
4508582d83SMateusz Kulikowski 	_rtl92e_eeprom_ck_cycle(dev);
463d461c91SSean MacLennan 
4708582d83SMateusz Kulikowski 	while (tx_len--) {
4808582d83SMateusz Kulikowski 		_rtl92e_gpio_write_bit(dev, EPROM_W_BIT,
4908582d83SMateusz Kulikowski 				       (data >> tx_len) & 0x1);
5008582d83SMateusz Kulikowski 		_rtl92e_eeprom_ck_cycle(dev);
513d461c91SSean MacLennan 	}
523d461c91SSean MacLennan 
5308582d83SMateusz Kulikowski 	_rtl92e_gpio_write_bit(dev, EPROM_W_BIT, 0);
543d461c91SSean MacLennan 
5508582d83SMateusz Kulikowski 	while (rx_len--) {
5608582d83SMateusz Kulikowski 		_rtl92e_eeprom_ck_cycle(dev);
5708582d83SMateusz Kulikowski 		ret |= _rtl92e_gpio_get_bit(dev, EPROM_R_BIT) << rx_len;
583d461c91SSean MacLennan 	}
5908582d83SMateusz Kulikowski 
6008582d83SMateusz Kulikowski 	_rtl92e_gpio_write_bit(dev, EPROM_CS_BIT, 0);
6108582d83SMateusz Kulikowski 	_rtl92e_eeprom_ck_cycle(dev);
6208582d83SMateusz Kulikowski 
6308582d83SMateusz Kulikowski 	return ret;
643d461c91SSean MacLennan }
653d461c91SSean MacLennan 
rtl92e_eeprom_read(struct net_device * dev,u32 addr)6668cb7b7aSMateusz Kulikowski u32 rtl92e_eeprom_read(struct net_device *dev, u32 addr)
673d461c91SSean MacLennan {
683d461c91SSean MacLennan 	struct r8192_priv *priv = rtllib_priv(dev);
6908582d83SMateusz Kulikowski 	u32 ret = 0;
703d461c91SSean MacLennan 
71d8ae1967SMateusz Kulikowski 	rtl92e_writeb(dev, EPROM_CMD,
723d461c91SSean MacLennan 		      (EPROM_CMD_PROGRAM << EPROM_CMD_OPERATING_MODE_SHIFT));
733d461c91SSean MacLennan 	udelay(EPROM_DELAY);
743d461c91SSean MacLennan 
7508582d83SMateusz Kulikowski 	/* EEPROM is configured as x16 */
7608582d83SMateusz Kulikowski 	if (priv->epromtype == EEPROM_93C56)
7708582d83SMateusz Kulikowski 		ret = _rtl92e_eeprom_xfer(dev, (addr & 0xFF) | (0x6 << 8), 11);
7808582d83SMateusz Kulikowski 	else
7908582d83SMateusz Kulikowski 		ret = _rtl92e_eeprom_xfer(dev, (addr & 0x3F) | (0x6 << 6), 9);
803d461c91SSean MacLennan 
81d8ae1967SMateusz Kulikowski 	rtl92e_writeb(dev, EPROM_CMD,
823d461c91SSean MacLennan 		      (EPROM_CMD_NORMAL << EPROM_CMD_OPERATING_MODE_SHIFT));
833d461c91SSean MacLennan 	return ret;
843d461c91SSean MacLennan }
85