root/drivers/media/pci/solo6x10/solo6x10-eeprom.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. solo_eeprom_reg_read
  2. solo_eeprom_reg_write
  3. solo_eeprom_cmd
  4. solo_eeprom_ewen
  5. solo_eeprom_read
  6. solo_eeprom_write

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * Copyright (C) 2010-2013 Bluecherry, LLC <http://www.bluecherrydvr.com>
   4  *
   5  * Original author:
   6  * Ben Collins <bcollins@ubuntu.com>
   7  *
   8  * Additional work by:
   9  * John Brooks <john.brooks@bluecherry.net>
  10  */
  11 
  12 #include <linux/kernel.h>
  13 #include <linux/delay.h>
  14 
  15 #include "solo6x10.h"
  16 
  17 /* Control */
  18 #define EE_SHIFT_CLK    0x04
  19 #define EE_CS           0x08
  20 #define EE_DATA_WRITE   0x02
  21 #define EE_DATA_READ    0x01
  22 #define EE_ENB          (0x80 | EE_CS)
  23 
  24 #define eeprom_delay()  udelay(100)
  25 #if 0
  26 #define eeprom_delay()  solo_reg_read(solo_dev, SOLO_EEPROM_CTRL)
  27 #define eeprom_delay()  ({                              \
  28         int i, ret;                                     \
  29         udelay(100);                                    \
  30         for (i = ret = 0; i < 1000 && !ret; i++)        \
  31                 ret = solo_eeprom_reg_read(solo_dev);   \
  32 })
  33 #endif
  34 #define ADDR_LEN        6
  35 
  36 /* Commands */
  37 #define EE_EWEN_CMD     4
  38 #define EE_EWDS_CMD     4
  39 #define EE_WRITE_CMD    5
  40 #define EE_READ_CMD     6
  41 #define EE_ERASE_CMD    7
  42 
  43 static unsigned int solo_eeprom_reg_read(struct solo_dev *solo_dev)
  44 {
  45         return solo_reg_read(solo_dev, SOLO_EEPROM_CTRL) & EE_DATA_READ;
  46 }
  47 
  48 static void solo_eeprom_reg_write(struct solo_dev *solo_dev, u32 data)
  49 {
  50         solo_reg_write(solo_dev, SOLO_EEPROM_CTRL, data);
  51         eeprom_delay();
  52 }
  53 
  54 static void solo_eeprom_cmd(struct solo_dev *solo_dev, int cmd)
  55 {
  56         int i;
  57 
  58         solo_eeprom_reg_write(solo_dev, SOLO_EEPROM_ACCESS_EN);
  59         solo_eeprom_reg_write(solo_dev, SOLO_EEPROM_ENABLE);
  60 
  61         for (i = 4 + ADDR_LEN; i >= 0; i--) {
  62                 int dataval = (cmd & (1 << i)) ? EE_DATA_WRITE : 0;
  63 
  64                 solo_eeprom_reg_write(solo_dev, SOLO_EEPROM_ENABLE | dataval);
  65                 solo_eeprom_reg_write(solo_dev, SOLO_EEPROM_ENABLE |
  66                                       EE_SHIFT_CLK | dataval);
  67         }
  68 
  69         solo_eeprom_reg_write(solo_dev, SOLO_EEPROM_ENABLE);
  70 }
  71 
  72 unsigned int solo_eeprom_ewen(struct solo_dev *solo_dev, int w_en)
  73 {
  74         int ewen_cmd = (w_en ? 0x3f : 0) | (EE_EWEN_CMD << ADDR_LEN);
  75         unsigned int retval = 0;
  76         int i;
  77 
  78         solo_eeprom_cmd(solo_dev, ewen_cmd);
  79 
  80         for (i = 0; i < 16; i++) {
  81                 solo_eeprom_reg_write(solo_dev, SOLO_EEPROM_ENABLE |
  82                                       EE_SHIFT_CLK);
  83                 retval = (retval << 1) | solo_eeprom_reg_read(solo_dev);
  84                 solo_eeprom_reg_write(solo_dev, SOLO_EEPROM_ENABLE);
  85                 retval = (retval << 1) | solo_eeprom_reg_read(solo_dev);
  86         }
  87 
  88         solo_eeprom_reg_write(solo_dev, ~EE_CS);
  89         retval = (retval << 1) | solo_eeprom_reg_read(solo_dev);
  90 
  91         return retval;
  92 }
  93 
  94 __be16 solo_eeprom_read(struct solo_dev *solo_dev, int loc)
  95 {
  96         int read_cmd = loc | (EE_READ_CMD << ADDR_LEN);
  97         u16 retval = 0;
  98         int i;
  99 
 100         solo_eeprom_cmd(solo_dev, read_cmd);
 101 
 102         for (i = 0; i < 16; i++) {
 103                 solo_eeprom_reg_write(solo_dev, SOLO_EEPROM_ENABLE |
 104                                       EE_SHIFT_CLK);
 105                 retval = (retval << 1) | solo_eeprom_reg_read(solo_dev);
 106                 solo_eeprom_reg_write(solo_dev, SOLO_EEPROM_ENABLE);
 107         }
 108 
 109         solo_eeprom_reg_write(solo_dev, ~EE_CS);
 110 
 111         return (__force __be16)retval;
 112 }
 113 
 114 int solo_eeprom_write(struct solo_dev *solo_dev, int loc,
 115                       __be16 data)
 116 {
 117         int write_cmd = loc | (EE_WRITE_CMD << ADDR_LEN);
 118         unsigned int retval;
 119         int i;
 120 
 121         solo_eeprom_cmd(solo_dev, write_cmd);
 122 
 123         for (i = 15; i >= 0; i--) {
 124                 unsigned int dataval = ((__force unsigned)data >> i) & 1;
 125 
 126                 solo_eeprom_reg_write(solo_dev, EE_ENB);
 127                 solo_eeprom_reg_write(solo_dev,
 128                                       EE_ENB | (dataval << 1) | EE_SHIFT_CLK);
 129         }
 130 
 131         solo_eeprom_reg_write(solo_dev, EE_ENB);
 132         solo_eeprom_reg_write(solo_dev, ~EE_CS);
 133         solo_eeprom_reg_write(solo_dev, EE_ENB);
 134 
 135         for (i = retval = 0; i < 10000 && !retval; i++)
 136                 retval = solo_eeprom_reg_read(solo_dev);
 137 
 138         solo_eeprom_reg_write(solo_dev, ~EE_CS);
 139 
 140         return !retval;
 141 }

/* [<][>][^][v][top][bottom][index][help] */