root/drivers/base/regmap/regmap-w1.c

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

DEFINITIONS

This source file includes following definitions.
  1. w1_reg_a8_v8_read
  2. w1_reg_a8_v8_write
  3. w1_reg_a8_v16_read
  4. w1_reg_a8_v16_write
  5. w1_reg_a16_v16_read
  6. w1_reg_a16_v16_write
  7. regmap_get_w1_bus
  8. __regmap_init_w1
  9. __devm_regmap_init_w1

   1 // SPDX-License-Identifier: GPL-2.0
   2 //
   3 // Register map access API - W1 (1-Wire) support
   4 //
   5 // Copyright (c) 2017 Radioavionica Corporation
   6 // Author: Alex A. Mihaylov <minimumlaw@rambler.ru>
   7 
   8 #include <linux/regmap.h>
   9 #include <linux/module.h>
  10 #include <linux/w1.h>
  11 
  12 #include "internal.h"
  13 
  14 #define W1_CMD_READ_DATA        0x69
  15 #define W1_CMD_WRITE_DATA       0x6C
  16 
  17 /*
  18  * 1-Wire slaves registers with addess 8 bit and data 8 bit
  19  */
  20 
  21 static int w1_reg_a8_v8_read(void *context, unsigned int reg, unsigned int *val)
  22 {
  23         struct device *dev = context;
  24         struct w1_slave *sl = container_of(dev, struct w1_slave, dev);
  25         int ret = 0;
  26 
  27         if (reg > 255)
  28                 return -EINVAL;
  29 
  30         mutex_lock(&sl->master->bus_mutex);
  31         if (!w1_reset_select_slave(sl)) {
  32                 w1_write_8(sl->master, W1_CMD_READ_DATA);
  33                 w1_write_8(sl->master, reg);
  34                 *val = w1_read_8(sl->master);
  35         } else {
  36                 ret = -ENODEV;
  37         }
  38         mutex_unlock(&sl->master->bus_mutex);
  39 
  40         return ret;
  41 }
  42 
  43 static int w1_reg_a8_v8_write(void *context, unsigned int reg, unsigned int val)
  44 {
  45         struct device *dev = context;
  46         struct w1_slave *sl = container_of(dev, struct w1_slave, dev);
  47         int ret = 0;
  48 
  49         if (reg > 255)
  50                 return -EINVAL;
  51 
  52         mutex_lock(&sl->master->bus_mutex);
  53         if (!w1_reset_select_slave(sl)) {
  54                 w1_write_8(sl->master, W1_CMD_WRITE_DATA);
  55                 w1_write_8(sl->master, reg);
  56                 w1_write_8(sl->master, val);
  57         } else {
  58                 ret = -ENODEV;
  59         }
  60         mutex_unlock(&sl->master->bus_mutex);
  61 
  62         return ret;
  63 }
  64 
  65 /*
  66  * 1-Wire slaves registers with addess 8 bit and data 16 bit
  67  */
  68 
  69 static int w1_reg_a8_v16_read(void *context, unsigned int reg,
  70                                 unsigned int *val)
  71 {
  72         struct device *dev = context;
  73         struct w1_slave *sl = container_of(dev, struct w1_slave, dev);
  74         int ret = 0;
  75 
  76         if (reg > 255)
  77                 return -EINVAL;
  78 
  79         mutex_lock(&sl->master->bus_mutex);
  80         if (!w1_reset_select_slave(sl)) {
  81                 w1_write_8(sl->master, W1_CMD_READ_DATA);
  82                 w1_write_8(sl->master, reg);
  83                 *val = w1_read_8(sl->master);
  84                 *val |= w1_read_8(sl->master)<<8;
  85         } else {
  86                 ret = -ENODEV;
  87         }
  88         mutex_unlock(&sl->master->bus_mutex);
  89 
  90         return ret;
  91 }
  92 
  93 static int w1_reg_a8_v16_write(void *context, unsigned int reg,
  94                                 unsigned int val)
  95 {
  96         struct device *dev = context;
  97         struct w1_slave *sl = container_of(dev, struct w1_slave, dev);
  98         int ret = 0;
  99 
 100         if (reg > 255)
 101                 return -EINVAL;
 102 
 103         mutex_lock(&sl->master->bus_mutex);
 104         if (!w1_reset_select_slave(sl)) {
 105                 w1_write_8(sl->master, W1_CMD_WRITE_DATA);
 106                 w1_write_8(sl->master, reg);
 107                 w1_write_8(sl->master, val & 0x00FF);
 108                 w1_write_8(sl->master, val>>8 & 0x00FF);
 109         } else {
 110                 ret = -ENODEV;
 111         }
 112         mutex_unlock(&sl->master->bus_mutex);
 113 
 114         return ret;
 115 }
 116 
 117 /*
 118  * 1-Wire slaves registers with addess 16 bit and data 16 bit
 119  */
 120 
 121 static int w1_reg_a16_v16_read(void *context, unsigned int reg,
 122                                 unsigned int *val)
 123 {
 124         struct device *dev = context;
 125         struct w1_slave *sl = container_of(dev, struct w1_slave, dev);
 126         int ret = 0;
 127 
 128         if (reg > 65535)
 129                 return -EINVAL;
 130 
 131         mutex_lock(&sl->master->bus_mutex);
 132         if (!w1_reset_select_slave(sl)) {
 133                 w1_write_8(sl->master, W1_CMD_READ_DATA);
 134                 w1_write_8(sl->master, reg & 0x00FF);
 135                 w1_write_8(sl->master, reg>>8 & 0x00FF);
 136                 *val = w1_read_8(sl->master);
 137                 *val |= w1_read_8(sl->master)<<8;
 138         } else {
 139                 ret = -ENODEV;
 140         }
 141         mutex_unlock(&sl->master->bus_mutex);
 142 
 143         return ret;
 144 }
 145 
 146 static int w1_reg_a16_v16_write(void *context, unsigned int reg,
 147                                 unsigned int val)
 148 {
 149         struct device *dev = context;
 150         struct w1_slave *sl = container_of(dev, struct w1_slave, dev);
 151         int ret = 0;
 152 
 153         if (reg > 65535)
 154                 return -EINVAL;
 155 
 156         mutex_lock(&sl->master->bus_mutex);
 157         if (!w1_reset_select_slave(sl)) {
 158                 w1_write_8(sl->master, W1_CMD_WRITE_DATA);
 159                 w1_write_8(sl->master, reg & 0x00FF);
 160                 w1_write_8(sl->master, reg>>8 & 0x00FF);
 161                 w1_write_8(sl->master, val & 0x00FF);
 162                 w1_write_8(sl->master, val>>8 & 0x00FF);
 163         } else {
 164                 ret = -ENODEV;
 165         }
 166         mutex_unlock(&sl->master->bus_mutex);
 167 
 168         return ret;
 169 }
 170 
 171 /*
 172  * Various types of supported bus addressing
 173  */
 174 
 175 static struct regmap_bus regmap_w1_bus_a8_v8 = {
 176         .reg_read = w1_reg_a8_v8_read,
 177         .reg_write = w1_reg_a8_v8_write,
 178 };
 179 
 180 static struct regmap_bus regmap_w1_bus_a8_v16 = {
 181         .reg_read = w1_reg_a8_v16_read,
 182         .reg_write = w1_reg_a8_v16_write,
 183 };
 184 
 185 static struct regmap_bus regmap_w1_bus_a16_v16 = {
 186         .reg_read = w1_reg_a16_v16_read,
 187         .reg_write = w1_reg_a16_v16_write,
 188 };
 189 
 190 static const struct regmap_bus *regmap_get_w1_bus(struct device *w1_dev,
 191                                         const struct regmap_config *config)
 192 {
 193         if (config->reg_bits == 8 && config->val_bits == 8)
 194                 return &regmap_w1_bus_a8_v8;
 195 
 196         if (config->reg_bits == 8 && config->val_bits == 16)
 197                 return &regmap_w1_bus_a8_v16;
 198 
 199         if (config->reg_bits == 16 && config->val_bits == 16)
 200                 return &regmap_w1_bus_a16_v16;
 201 
 202         return ERR_PTR(-ENOTSUPP);
 203 }
 204 
 205 struct regmap *__regmap_init_w1(struct device *w1_dev,
 206                                  const struct regmap_config *config,
 207                                  struct lock_class_key *lock_key,
 208                                  const char *lock_name)
 209 {
 210 
 211         const struct regmap_bus *bus = regmap_get_w1_bus(w1_dev, config);
 212 
 213         if (IS_ERR(bus))
 214                 return ERR_CAST(bus);
 215 
 216         return __regmap_init(w1_dev, bus, w1_dev, config,
 217                          lock_key, lock_name);
 218 
 219         return NULL;
 220 }
 221 EXPORT_SYMBOL_GPL(__regmap_init_w1);
 222 
 223 struct regmap *__devm_regmap_init_w1(struct device *w1_dev,
 224                                  const struct regmap_config *config,
 225                                  struct lock_class_key *lock_key,
 226                                  const char *lock_name)
 227 {
 228 
 229         const struct regmap_bus *bus = regmap_get_w1_bus(w1_dev, config);
 230 
 231         if (IS_ERR(bus))
 232                 return ERR_CAST(bus);
 233 
 234         return __devm_regmap_init(w1_dev, bus, w1_dev, config,
 235                                  lock_key, lock_name);
 236 
 237         return NULL;
 238 }
 239 EXPORT_SYMBOL_GPL(__devm_regmap_init_w1);
 240 
 241 MODULE_LICENSE("GPL");

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