Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Copyright (C) 2010-2013 Bluecherry, LLC <https://www.bluecherrydvr.com>
0004  *
0005  * Original author:
0006  * Ben Collins <bcollins@ubuntu.com>
0007  *
0008  * Additional work by:
0009  * John Brooks <john.brooks@bluecherry.net>
0010  */
0011 
0012 #include <linux/kernel.h>
0013 #include <linux/delay.h>
0014 
0015 #include "solo6x10.h"
0016 
0017 /* Control */
0018 #define EE_SHIFT_CLK    0x04
0019 #define EE_CS       0x08
0020 #define EE_DATA_WRITE   0x02
0021 #define EE_DATA_READ    0x01
0022 #define EE_ENB      (0x80 | EE_CS)
0023 
0024 #define eeprom_delay()  udelay(100)
0025 #if 0
0026 #define eeprom_delay()  solo_reg_read(solo_dev, SOLO_EEPROM_CTRL)
0027 #define eeprom_delay()  ({              \
0028     int i, ret;                 \
0029     udelay(100);                    \
0030     for (i = ret = 0; i < 1000 && !ret; i++)    \
0031         ret = solo_eeprom_reg_read(solo_dev);   \
0032 })
0033 #endif
0034 #define ADDR_LEN    6
0035 
0036 /* Commands */
0037 #define EE_EWEN_CMD 4
0038 #define EE_EWDS_CMD 4
0039 #define EE_WRITE_CMD    5
0040 #define EE_READ_CMD 6
0041 #define EE_ERASE_CMD    7
0042 
0043 static unsigned int solo_eeprom_reg_read(struct solo_dev *solo_dev)
0044 {
0045     return solo_reg_read(solo_dev, SOLO_EEPROM_CTRL) & EE_DATA_READ;
0046 }
0047 
0048 static void solo_eeprom_reg_write(struct solo_dev *solo_dev, u32 data)
0049 {
0050     solo_reg_write(solo_dev, SOLO_EEPROM_CTRL, data);
0051     eeprom_delay();
0052 }
0053 
0054 static void solo_eeprom_cmd(struct solo_dev *solo_dev, int cmd)
0055 {
0056     int i;
0057 
0058     solo_eeprom_reg_write(solo_dev, SOLO_EEPROM_ACCESS_EN);
0059     solo_eeprom_reg_write(solo_dev, SOLO_EEPROM_ENABLE);
0060 
0061     for (i = 4 + ADDR_LEN; i >= 0; i--) {
0062         int dataval = (cmd & (1 << i)) ? EE_DATA_WRITE : 0;
0063 
0064         solo_eeprom_reg_write(solo_dev, SOLO_EEPROM_ENABLE | dataval);
0065         solo_eeprom_reg_write(solo_dev, SOLO_EEPROM_ENABLE |
0066                       EE_SHIFT_CLK | dataval);
0067     }
0068 
0069     solo_eeprom_reg_write(solo_dev, SOLO_EEPROM_ENABLE);
0070 }
0071 
0072 unsigned int solo_eeprom_ewen(struct solo_dev *solo_dev, int w_en)
0073 {
0074     int ewen_cmd = (w_en ? 0x3f : 0) | (EE_EWEN_CMD << ADDR_LEN);
0075     unsigned int retval = 0;
0076     int i;
0077 
0078     solo_eeprom_cmd(solo_dev, ewen_cmd);
0079 
0080     for (i = 0; i < 16; i++) {
0081         solo_eeprom_reg_write(solo_dev, SOLO_EEPROM_ENABLE |
0082                       EE_SHIFT_CLK);
0083         retval = (retval << 1) | solo_eeprom_reg_read(solo_dev);
0084         solo_eeprom_reg_write(solo_dev, SOLO_EEPROM_ENABLE);
0085         retval = (retval << 1) | solo_eeprom_reg_read(solo_dev);
0086     }
0087 
0088     solo_eeprom_reg_write(solo_dev, ~EE_CS);
0089     retval = (retval << 1) | solo_eeprom_reg_read(solo_dev);
0090 
0091     return retval;
0092 }
0093 
0094 __be16 solo_eeprom_read(struct solo_dev *solo_dev, int loc)
0095 {
0096     int read_cmd = loc | (EE_READ_CMD << ADDR_LEN);
0097     u16 retval = 0;
0098     int i;
0099 
0100     solo_eeprom_cmd(solo_dev, read_cmd);
0101 
0102     for (i = 0; i < 16; i++) {
0103         solo_eeprom_reg_write(solo_dev, SOLO_EEPROM_ENABLE |
0104                       EE_SHIFT_CLK);
0105         retval = (retval << 1) | solo_eeprom_reg_read(solo_dev);
0106         solo_eeprom_reg_write(solo_dev, SOLO_EEPROM_ENABLE);
0107     }
0108 
0109     solo_eeprom_reg_write(solo_dev, ~EE_CS);
0110 
0111     return (__force __be16)retval;
0112 }
0113 
0114 int solo_eeprom_write(struct solo_dev *solo_dev, int loc,
0115               __be16 data)
0116 {
0117     int write_cmd = loc | (EE_WRITE_CMD << ADDR_LEN);
0118     unsigned int retval;
0119     int i;
0120 
0121     solo_eeprom_cmd(solo_dev, write_cmd);
0122 
0123     for (i = 15; i >= 0; i--) {
0124         unsigned int dataval = ((__force unsigned)data >> i) & 1;
0125 
0126         solo_eeprom_reg_write(solo_dev, EE_ENB);
0127         solo_eeprom_reg_write(solo_dev,
0128                       EE_ENB | (dataval << 1) | EE_SHIFT_CLK);
0129     }
0130 
0131     solo_eeprom_reg_write(solo_dev, EE_ENB);
0132     solo_eeprom_reg_write(solo_dev, ~EE_CS);
0133     solo_eeprom_reg_write(solo_dev, EE_ENB);
0134 
0135     for (i = retval = 0; i < 10000 && !retval; i++)
0136         retval = solo_eeprom_reg_read(solo_dev);
0137 
0138     solo_eeprom_reg_write(solo_dev, ~EE_CS);
0139 
0140     return !retval;
0141 }