root/drivers/net/wan/slic_ds26522.c

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

DEFINITIONS

This source file includes following definitions.
  1. slic_write
  2. slic_read
  3. get_slic_product_code
  4. ds26522_e1_spec_config
  5. slic_ds26522_init_configure
  6. slic_ds26522_remove
  7. slic_ds26522_probe

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * drivers/net/wan/slic_ds26522.c
   4  *
   5  * Copyright (C) 2016 Freescale Semiconductor, Inc.
   6  *
   7  * Author:Zhao Qiang<qiang.zhao@nxp.com>
   8  */
   9 
  10 #include <linux/bitrev.h>
  11 #include <linux/module.h>
  12 #include <linux/device.h>
  13 #include <linux/kernel.h>
  14 #include <linux/sched.h>
  15 #include <linux/kthread.h>
  16 #include <linux/spi/spi.h>
  17 #include <linux/wait.h>
  18 #include <linux/param.h>
  19 #include <linux/delay.h>
  20 #include <linux/of.h>
  21 #include <linux/of_address.h>
  22 #include <linux/io.h>
  23 #include "slic_ds26522.h"
  24 
  25 #define DRV_NAME "ds26522"
  26 
  27 #define SLIC_TRANS_LEN 1
  28 #define SLIC_TWO_LEN 2
  29 #define SLIC_THREE_LEN 3
  30 
  31 static struct spi_device *g_spi;
  32 
  33 MODULE_LICENSE("GPL");
  34 MODULE_AUTHOR("Zhao Qiang<B45475@freescale.com>");
  35 
  36 /* the read/write format of address is
  37  * w/r|A13|A12|A11|A10|A9|A8|A7|A6|A5|A4|A3|A2|A1|A0|x
  38  */
  39 static void slic_write(struct spi_device *spi, u16 addr,
  40                        u8 data)
  41 {
  42         u8 temp[3];
  43 
  44         addr = bitrev16(addr) >> 1;
  45         data = bitrev8(data);
  46         temp[0] = (u8)((addr >> 8) & 0x7f);
  47         temp[1] = (u8)(addr & 0xfe);
  48         temp[2] = data;
  49 
  50         /* write spi addr and value */
  51         spi_write(spi, &temp[0], SLIC_THREE_LEN);
  52 }
  53 
  54 static u8 slic_read(struct spi_device *spi, u16 addr)
  55 {
  56         u8 temp[2];
  57         u8 data;
  58 
  59         addr = bitrev16(addr) >> 1;
  60         temp[0] = (u8)(((addr >> 8) & 0x7f) | 0x80);
  61         temp[1] = (u8)(addr & 0xfe);
  62 
  63         spi_write_then_read(spi, &temp[0], SLIC_TWO_LEN, &data,
  64                             SLIC_TRANS_LEN);
  65 
  66         data = bitrev8(data);
  67         return data;
  68 }
  69 
  70 static bool get_slic_product_code(struct spi_device *spi)
  71 {
  72         u8 device_id;
  73 
  74         device_id = slic_read(spi, DS26522_IDR_ADDR);
  75         if ((device_id & 0xf8) == 0x68)
  76                 return true;
  77         else
  78                 return false;
  79 }
  80 
  81 static void ds26522_e1_spec_config(struct spi_device *spi)
  82 {
  83         /* Receive E1 Mode, Framer Disabled */
  84         slic_write(spi, DS26522_RMMR_ADDR, DS26522_RMMR_E1);
  85 
  86         /* Transmit E1 Mode, Framer Disable */
  87         slic_write(spi, DS26522_TMMR_ADDR, DS26522_TMMR_E1);
  88 
  89         /* Receive E1 Mode Framer Enable */
  90         slic_write(spi, DS26522_RMMR_ADDR,
  91                    slic_read(spi, DS26522_RMMR_ADDR) | DS26522_RMMR_FRM_EN);
  92 
  93         /* Transmit E1 Mode Framer Enable */
  94         slic_write(spi, DS26522_TMMR_ADDR,
  95                    slic_read(spi, DS26522_TMMR_ADDR) | DS26522_TMMR_FRM_EN);
  96 
  97         /* RCR1, receive E1 B8zs & ESF */
  98         slic_write(spi, DS26522_RCR1_ADDR,
  99                    DS26522_RCR1_E1_HDB3 | DS26522_RCR1_E1_CCS);
 100 
 101         /* RSYSCLK=2.048MHz, RSYNC-Output */
 102         slic_write(spi, DS26522_RIOCR_ADDR,
 103                    DS26522_RIOCR_2048KHZ | DS26522_RIOCR_RSIO_OUT);
 104 
 105         /* TCR1 Transmit E1 b8zs */
 106         slic_write(spi, DS26522_TCR1_ADDR, DS26522_TCR1_TB8ZS);
 107 
 108         /* TSYSCLK=2.048MHz, TSYNC-Output */
 109         slic_write(spi, DS26522_TIOCR_ADDR,
 110                    DS26522_TIOCR_2048KHZ | DS26522_TIOCR_TSIO_OUT);
 111 
 112         /* Set E1TAF */
 113         slic_write(spi, DS26522_E1TAF_ADDR, DS26522_E1TAF_DEFAULT);
 114 
 115         /* Set E1TNAF register */
 116         slic_write(spi, DS26522_E1TNAF_ADDR, DS26522_E1TNAF_DEFAULT);
 117 
 118         /* Receive E1 Mode Framer Enable & init Done */
 119         slic_write(spi, DS26522_RMMR_ADDR, slic_read(spi, DS26522_RMMR_ADDR) |
 120                    DS26522_RMMR_INIT_DONE);
 121 
 122         /* Transmit E1 Mode Framer Enable & init Done */
 123         slic_write(spi, DS26522_TMMR_ADDR, slic_read(spi, DS26522_TMMR_ADDR) |
 124                    DS26522_TMMR_INIT_DONE);
 125 
 126         /* Configure LIU E1 mode */
 127         slic_write(spi, DS26522_LTRCR_ADDR, DS26522_LTRCR_E1);
 128 
 129         /* E1 Mode default 75 ohm w/Transmit Impedance Matlinking */
 130         slic_write(spi, DS26522_LTITSR_ADDR,
 131                    DS26522_LTITSR_TLIS_75OHM | DS26522_LTITSR_LBOS_75OHM);
 132 
 133         /* E1 Mode default 75 ohm Long Haul w/Receive Impedance Matlinking */
 134         slic_write(spi, DS26522_LRISMR_ADDR,
 135                    DS26522_LRISMR_75OHM | DS26522_LRISMR_MAX);
 136 
 137         /* Enable Transmit output */
 138         slic_write(spi, DS26522_LMCR_ADDR, DS26522_LMCR_TE);
 139 }
 140 
 141 static int slic_ds26522_init_configure(struct spi_device *spi)
 142 {
 143         u16 addr;
 144 
 145         /* set clock */
 146         slic_write(spi, DS26522_GTCCR_ADDR, DS26522_GTCCR_BPREFSEL_REFCLKIN |
 147                         DS26522_GTCCR_BFREQSEL_2048KHZ |
 148                         DS26522_GTCCR_FREQSEL_2048KHZ);
 149         slic_write(spi, DS26522_GTCR2_ADDR, DS26522_GTCR2_TSSYNCOUT);
 150         slic_write(spi, DS26522_GFCR_ADDR, DS26522_GFCR_BPCLK_2048KHZ);
 151 
 152         /* set gtcr */
 153         slic_write(spi, DS26522_GTCR1_ADDR, DS26522_GTCR1);
 154 
 155         /* Global LIU Software Reset Register */
 156         slic_write(spi, DS26522_GLSRR_ADDR, DS26522_GLSRR_RESET);
 157 
 158         /* Global Framer and BERT Software Reset Register */
 159         slic_write(spi, DS26522_GFSRR_ADDR, DS26522_GFSRR_RESET);
 160 
 161         usleep_range(100, 120);
 162 
 163         slic_write(spi, DS26522_GLSRR_ADDR, DS26522_GLSRR_NORMAL);
 164         slic_write(spi, DS26522_GFSRR_ADDR, DS26522_GFSRR_NORMAL);
 165 
 166         /* Perform RX/TX SRESET,Reset receiver */
 167         slic_write(spi, DS26522_RMMR_ADDR, DS26522_RMMR_SFTRST);
 168 
 169         /* Reset tranceiver */
 170         slic_write(spi, DS26522_TMMR_ADDR, DS26522_TMMR_SFTRST);
 171 
 172         usleep_range(100, 120);
 173 
 174         /* Zero all Framer Registers */
 175         for (addr = DS26522_RF_ADDR_START; addr <= DS26522_RF_ADDR_END;
 176              addr++)
 177                 slic_write(spi, addr, 0);
 178 
 179         for (addr = DS26522_TF_ADDR_START; addr <= DS26522_TF_ADDR_END;
 180              addr++)
 181                 slic_write(spi, addr, 0);
 182 
 183         for (addr = DS26522_LIU_ADDR_START; addr <= DS26522_LIU_ADDR_END;
 184              addr++)
 185                 slic_write(spi, addr, 0);
 186 
 187         for (addr = DS26522_BERT_ADDR_START; addr <= DS26522_BERT_ADDR_END;
 188              addr++)
 189                 slic_write(spi, addr, 0);
 190 
 191         /* setup ds26522 for E1 specification */
 192         ds26522_e1_spec_config(spi);
 193 
 194         slic_write(spi, DS26522_GTCR1_ADDR, 0x00);
 195 
 196         return 0;
 197 }
 198 
 199 static int slic_ds26522_remove(struct spi_device *spi)
 200 {
 201         pr_info("DS26522 module uninstalled\n");
 202         return 0;
 203 }
 204 
 205 static int slic_ds26522_probe(struct spi_device *spi)
 206 {
 207         int ret = 0;
 208 
 209         g_spi = spi;
 210         spi->bits_per_word = 8;
 211 
 212         if (!get_slic_product_code(spi))
 213                 return ret;
 214 
 215         ret = slic_ds26522_init_configure(spi);
 216         if (ret == 0)
 217                 pr_info("DS26522 cs%d configured\n", spi->chip_select);
 218 
 219         return ret;
 220 }
 221 
 222 static const struct spi_device_id slic_ds26522_id[] = {
 223         { .name = "ds26522" },
 224         { /* sentinel */ },
 225 };
 226 MODULE_DEVICE_TABLE(spi, slic_ds26522_id);
 227 
 228 static const struct of_device_id slic_ds26522_match[] = {
 229         {
 230          .compatible = "maxim,ds26522",
 231          },
 232         {},
 233 };
 234 MODULE_DEVICE_TABLE(of, slic_ds26522_match);
 235 
 236 static struct spi_driver slic_ds26522_driver = {
 237         .driver = {
 238                    .name = "ds26522",
 239                    .bus = &spi_bus_type,
 240                    .of_match_table = slic_ds26522_match,
 241                    },
 242         .probe = slic_ds26522_probe,
 243         .remove = slic_ds26522_remove,
 244         .id_table = slic_ds26522_id,
 245 };
 246 
 247 module_spi_driver(slic_ds26522_driver);

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