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