1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. |
4 | * |
5 | * Based on the r8180 driver, which is: |
6 | * Copyright 2004-2005 Andrea Merello <andrea.merello@gmail.com>, et al. |
7 | * |
8 | * Contact Information: wlanfae <wlanfae@realtek.com> |
9 | */ |
10 | #include "rtl_core.h" |
11 | #include "rtl_eeprom.h" |
12 | |
13 | static void _rtl92e_gpio_write_bit(struct net_device *dev, int no, bool val) |
14 | { |
15 | u8 reg = rtl92e_readb(dev, x: EPROM_CMD); |
16 | |
17 | if (val) |
18 | reg |= 1 << no; |
19 | else |
20 | reg &= ~(1 << no); |
21 | |
22 | rtl92e_writeb(dev, x: EPROM_CMD, y: reg); |
23 | udelay(EPROM_DELAY); |
24 | } |
25 | |
26 | static bool _rtl92e_gpio_get_bit(struct net_device *dev, int no) |
27 | { |
28 | u8 reg = rtl92e_readb(dev, x: EPROM_CMD); |
29 | |
30 | return (reg >> no) & 0x1; |
31 | } |
32 | |
33 | static void _rtl92e_eeprom_ck_cycle(struct net_device *dev) |
34 | { |
35 | _rtl92e_gpio_write_bit(dev, EPROM_CK_BIT, val: 1); |
36 | _rtl92e_gpio_write_bit(dev, EPROM_CK_BIT, val: 0); |
37 | } |
38 | |
39 | static u16 _rtl92e_eeprom_xfer(struct net_device *dev, u16 data, int tx_len) |
40 | { |
41 | u16 ret = 0; |
42 | int rx_len = 16; |
43 | |
44 | _rtl92e_gpio_write_bit(dev, EPROM_CS_BIT, val: 1); |
45 | _rtl92e_eeprom_ck_cycle(dev); |
46 | |
47 | while (tx_len--) { |
48 | _rtl92e_gpio_write_bit(dev, EPROM_W_BIT, |
49 | val: (data >> tx_len) & 0x1); |
50 | _rtl92e_eeprom_ck_cycle(dev); |
51 | } |
52 | |
53 | _rtl92e_gpio_write_bit(dev, EPROM_W_BIT, val: 0); |
54 | |
55 | while (rx_len--) { |
56 | _rtl92e_eeprom_ck_cycle(dev); |
57 | ret |= _rtl92e_gpio_get_bit(dev, EPROM_R_BIT) << rx_len; |
58 | } |
59 | |
60 | _rtl92e_gpio_write_bit(dev, EPROM_CS_BIT, val: 0); |
61 | _rtl92e_eeprom_ck_cycle(dev); |
62 | |
63 | return ret; |
64 | } |
65 | |
66 | u32 rtl92e_eeprom_read(struct net_device *dev, u32 addr) |
67 | { |
68 | struct r8192_priv *priv = rtllib_priv(dev); |
69 | u32 ret = 0; |
70 | |
71 | rtl92e_writeb(dev, x: EPROM_CMD, |
72 | y: (EPROM_CMD_PROGRAM << EPROM_CMD_OPERATING_MODE_SHIFT)); |
73 | udelay(EPROM_DELAY); |
74 | |
75 | /* EEPROM is configured as x16 */ |
76 | if (priv->epromtype == EEPROM_93C56) |
77 | ret = _rtl92e_eeprom_xfer(dev, data: (addr & 0xFF) | (0x6 << 8), tx_len: 11); |
78 | else |
79 | ret = _rtl92e_eeprom_xfer(dev, data: (addr & 0x3F) | (0x6 << 6), tx_len: 9); |
80 | |
81 | rtl92e_writeb(dev, x: EPROM_CMD, |
82 | y: (EPROM_CMD_NORMAL << EPROM_CMD_OPERATING_MODE_SHIFT)); |
83 | return ret; |
84 | } |
85 | |