Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 //
0003 // Register map access API - W1 (1-Wire) support
0004 //
0005 // Copyright (c) 2017 Radioavionica Corporation
0006 // Author: Alex A. Mihaylov <minimumlaw@rambler.ru>
0007 
0008 #include <linux/regmap.h>
0009 #include <linux/module.h>
0010 #include <linux/w1.h>
0011 
0012 #include "internal.h"
0013 
0014 #define W1_CMD_READ_DATA    0x69
0015 #define W1_CMD_WRITE_DATA   0x6C
0016 
0017 /*
0018  * 1-Wire slaves registers with addess 8 bit and data 8 bit
0019  */
0020 
0021 static int w1_reg_a8_v8_read(void *context, unsigned int reg, unsigned int *val)
0022 {
0023     struct device *dev = context;
0024     struct w1_slave *sl = container_of(dev, struct w1_slave, dev);
0025     int ret = 0;
0026 
0027     if (reg > 255)
0028         return -EINVAL;
0029 
0030     mutex_lock(&sl->master->bus_mutex);
0031     if (!w1_reset_select_slave(sl)) {
0032         w1_write_8(sl->master, W1_CMD_READ_DATA);
0033         w1_write_8(sl->master, reg);
0034         *val = w1_read_8(sl->master);
0035     } else {
0036         ret = -ENODEV;
0037     }
0038     mutex_unlock(&sl->master->bus_mutex);
0039 
0040     return ret;
0041 }
0042 
0043 static int w1_reg_a8_v8_write(void *context, unsigned int reg, unsigned int val)
0044 {
0045     struct device *dev = context;
0046     struct w1_slave *sl = container_of(dev, struct w1_slave, dev);
0047     int ret = 0;
0048 
0049     if (reg > 255)
0050         return -EINVAL;
0051 
0052     mutex_lock(&sl->master->bus_mutex);
0053     if (!w1_reset_select_slave(sl)) {
0054         w1_write_8(sl->master, W1_CMD_WRITE_DATA);
0055         w1_write_8(sl->master, reg);
0056         w1_write_8(sl->master, val);
0057     } else {
0058         ret = -ENODEV;
0059     }
0060     mutex_unlock(&sl->master->bus_mutex);
0061 
0062     return ret;
0063 }
0064 
0065 /*
0066  * 1-Wire slaves registers with addess 8 bit and data 16 bit
0067  */
0068 
0069 static int w1_reg_a8_v16_read(void *context, unsigned int reg,
0070                 unsigned int *val)
0071 {
0072     struct device *dev = context;
0073     struct w1_slave *sl = container_of(dev, struct w1_slave, dev);
0074     int ret = 0;
0075 
0076     if (reg > 255)
0077         return -EINVAL;
0078 
0079     mutex_lock(&sl->master->bus_mutex);
0080     if (!w1_reset_select_slave(sl)) {
0081         w1_write_8(sl->master, W1_CMD_READ_DATA);
0082         w1_write_8(sl->master, reg);
0083         *val = w1_read_8(sl->master);
0084         *val |= w1_read_8(sl->master)<<8;
0085     } else {
0086         ret = -ENODEV;
0087     }
0088     mutex_unlock(&sl->master->bus_mutex);
0089 
0090     return ret;
0091 }
0092 
0093 static int w1_reg_a8_v16_write(void *context, unsigned int reg,
0094                 unsigned int val)
0095 {
0096     struct device *dev = context;
0097     struct w1_slave *sl = container_of(dev, struct w1_slave, dev);
0098     int ret = 0;
0099 
0100     if (reg > 255)
0101         return -EINVAL;
0102 
0103     mutex_lock(&sl->master->bus_mutex);
0104     if (!w1_reset_select_slave(sl)) {
0105         w1_write_8(sl->master, W1_CMD_WRITE_DATA);
0106         w1_write_8(sl->master, reg);
0107         w1_write_8(sl->master, val & 0x00FF);
0108         w1_write_8(sl->master, val>>8 & 0x00FF);
0109     } else {
0110         ret = -ENODEV;
0111     }
0112     mutex_unlock(&sl->master->bus_mutex);
0113 
0114     return ret;
0115 }
0116 
0117 /*
0118  * 1-Wire slaves registers with addess 16 bit and data 16 bit
0119  */
0120 
0121 static int w1_reg_a16_v16_read(void *context, unsigned int reg,
0122                 unsigned int *val)
0123 {
0124     struct device *dev = context;
0125     struct w1_slave *sl = container_of(dev, struct w1_slave, dev);
0126     int ret = 0;
0127 
0128     if (reg > 65535)
0129         return -EINVAL;
0130 
0131     mutex_lock(&sl->master->bus_mutex);
0132     if (!w1_reset_select_slave(sl)) {
0133         w1_write_8(sl->master, W1_CMD_READ_DATA);
0134         w1_write_8(sl->master, reg & 0x00FF);
0135         w1_write_8(sl->master, reg>>8 & 0x00FF);
0136         *val = w1_read_8(sl->master);
0137         *val |= w1_read_8(sl->master)<<8;
0138     } else {
0139         ret = -ENODEV;
0140     }
0141     mutex_unlock(&sl->master->bus_mutex);
0142 
0143     return ret;
0144 }
0145 
0146 static int w1_reg_a16_v16_write(void *context, unsigned int reg,
0147                 unsigned int val)
0148 {
0149     struct device *dev = context;
0150     struct w1_slave *sl = container_of(dev, struct w1_slave, dev);
0151     int ret = 0;
0152 
0153     if (reg > 65535)
0154         return -EINVAL;
0155 
0156     mutex_lock(&sl->master->bus_mutex);
0157     if (!w1_reset_select_slave(sl)) {
0158         w1_write_8(sl->master, W1_CMD_WRITE_DATA);
0159         w1_write_8(sl->master, reg & 0x00FF);
0160         w1_write_8(sl->master, reg>>8 & 0x00FF);
0161         w1_write_8(sl->master, val & 0x00FF);
0162         w1_write_8(sl->master, val>>8 & 0x00FF);
0163     } else {
0164         ret = -ENODEV;
0165     }
0166     mutex_unlock(&sl->master->bus_mutex);
0167 
0168     return ret;
0169 }
0170 
0171 /*
0172  * Various types of supported bus addressing
0173  */
0174 
0175 static const struct regmap_bus regmap_w1_bus_a8_v8 = {
0176     .reg_read = w1_reg_a8_v8_read,
0177     .reg_write = w1_reg_a8_v8_write,
0178 };
0179 
0180 static const struct regmap_bus regmap_w1_bus_a8_v16 = {
0181     .reg_read = w1_reg_a8_v16_read,
0182     .reg_write = w1_reg_a8_v16_write,
0183 };
0184 
0185 static const struct regmap_bus regmap_w1_bus_a16_v16 = {
0186     .reg_read = w1_reg_a16_v16_read,
0187     .reg_write = w1_reg_a16_v16_write,
0188 };
0189 
0190 static const struct regmap_bus *regmap_get_w1_bus(struct device *w1_dev,
0191                     const struct regmap_config *config)
0192 {
0193     if (config->reg_bits == 8 && config->val_bits == 8)
0194         return &regmap_w1_bus_a8_v8;
0195 
0196     if (config->reg_bits == 8 && config->val_bits == 16)
0197         return &regmap_w1_bus_a8_v16;
0198 
0199     if (config->reg_bits == 16 && config->val_bits == 16)
0200         return &regmap_w1_bus_a16_v16;
0201 
0202     return ERR_PTR(-ENOTSUPP);
0203 }
0204 
0205 struct regmap *__regmap_init_w1(struct device *w1_dev,
0206                  const struct regmap_config *config,
0207                  struct lock_class_key *lock_key,
0208                  const char *lock_name)
0209 {
0210 
0211     const struct regmap_bus *bus = regmap_get_w1_bus(w1_dev, config);
0212 
0213     if (IS_ERR(bus))
0214         return ERR_CAST(bus);
0215 
0216     return __regmap_init(w1_dev, bus, w1_dev, config,
0217              lock_key, lock_name);
0218 }
0219 EXPORT_SYMBOL_GPL(__regmap_init_w1);
0220 
0221 struct regmap *__devm_regmap_init_w1(struct device *w1_dev,
0222                  const struct regmap_config *config,
0223                  struct lock_class_key *lock_key,
0224                  const char *lock_name)
0225 {
0226 
0227     const struct regmap_bus *bus = regmap_get_w1_bus(w1_dev, config);
0228 
0229     if (IS_ERR(bus))
0230         return ERR_CAST(bus);
0231 
0232     return __devm_regmap_init(w1_dev, bus, w1_dev, config,
0233                  lock_key, lock_name);
0234 }
0235 EXPORT_SYMBOL_GPL(__devm_regmap_init_w1);
0236 
0237 MODULE_LICENSE("GPL");