1*2df8e64eSIvan Vecera // SPDX-License-Identifier: GPL-2.0-only 2*2df8e64eSIvan Vecera 3*2df8e64eSIvan Vecera #include <linux/array_size.h> 4*2df8e64eSIvan Vecera #include <linux/bitfield.h> 5*2df8e64eSIvan Vecera #include <linux/bits.h> 6*2df8e64eSIvan Vecera #include <linux/dev_printk.h> 7*2df8e64eSIvan Vecera #include <linux/device.h> 8*2df8e64eSIvan Vecera #include <linux/export.h> 9*2df8e64eSIvan Vecera #include <linux/module.h> 10*2df8e64eSIvan Vecera #include <linux/netlink.h> 11*2df8e64eSIvan Vecera #include <linux/regmap.h> 12*2df8e64eSIvan Vecera #include <linux/sprintf.h> 13*2df8e64eSIvan Vecera #include <linux/unaligned.h> 14*2df8e64eSIvan Vecera #include <net/devlink.h> 15*2df8e64eSIvan Vecera 16*2df8e64eSIvan Vecera #include "core.h" 17*2df8e64eSIvan Vecera #include "devlink.h" 18*2df8e64eSIvan Vecera #include "regs.h" 19*2df8e64eSIvan Vecera 20*2df8e64eSIvan Vecera /* Chip IDs for zl30731 */ 21*2df8e64eSIvan Vecera static const u16 zl30731_ids[] = { 22*2df8e64eSIvan Vecera 0x0E93, 23*2df8e64eSIvan Vecera 0x1E93, 24*2df8e64eSIvan Vecera 0x2E93, 25*2df8e64eSIvan Vecera }; 26*2df8e64eSIvan Vecera 27*2df8e64eSIvan Vecera const struct zl3073x_chip_info zl30731_chip_info = { 28*2df8e64eSIvan Vecera .ids = zl30731_ids, 29*2df8e64eSIvan Vecera .num_ids = ARRAY_SIZE(zl30731_ids), 30*2df8e64eSIvan Vecera .num_channels = 1, 31*2df8e64eSIvan Vecera }; 32*2df8e64eSIvan Vecera EXPORT_SYMBOL_NS_GPL(zl30731_chip_info, "ZL3073X"); 33*2df8e64eSIvan Vecera 34*2df8e64eSIvan Vecera /* Chip IDs for zl30732 */ 35*2df8e64eSIvan Vecera static const u16 zl30732_ids[] = { 36*2df8e64eSIvan Vecera 0x0E30, 37*2df8e64eSIvan Vecera 0x0E94, 38*2df8e64eSIvan Vecera 0x1E94, 39*2df8e64eSIvan Vecera 0x1F60, 40*2df8e64eSIvan Vecera 0x2E94, 41*2df8e64eSIvan Vecera 0x3FC4, 42*2df8e64eSIvan Vecera }; 43*2df8e64eSIvan Vecera 44*2df8e64eSIvan Vecera const struct zl3073x_chip_info zl30732_chip_info = { 45*2df8e64eSIvan Vecera .ids = zl30732_ids, 46*2df8e64eSIvan Vecera .num_ids = ARRAY_SIZE(zl30732_ids), 47*2df8e64eSIvan Vecera .num_channels = 2, 48*2df8e64eSIvan Vecera }; 49*2df8e64eSIvan Vecera EXPORT_SYMBOL_NS_GPL(zl30732_chip_info, "ZL3073X"); 50*2df8e64eSIvan Vecera 51*2df8e64eSIvan Vecera /* Chip IDs for zl30733 */ 52*2df8e64eSIvan Vecera static const u16 zl30733_ids[] = { 53*2df8e64eSIvan Vecera 0x0E95, 54*2df8e64eSIvan Vecera 0x1E95, 55*2df8e64eSIvan Vecera 0x2E95, 56*2df8e64eSIvan Vecera }; 57*2df8e64eSIvan Vecera 58*2df8e64eSIvan Vecera const struct zl3073x_chip_info zl30733_chip_info = { 59*2df8e64eSIvan Vecera .ids = zl30733_ids, 60*2df8e64eSIvan Vecera .num_ids = ARRAY_SIZE(zl30733_ids), 61*2df8e64eSIvan Vecera .num_channels = 3, 62*2df8e64eSIvan Vecera }; 63*2df8e64eSIvan Vecera EXPORT_SYMBOL_NS_GPL(zl30733_chip_info, "ZL3073X"); 64*2df8e64eSIvan Vecera 65*2df8e64eSIvan Vecera /* Chip IDs for zl30734 */ 66*2df8e64eSIvan Vecera static const u16 zl30734_ids[] = { 67*2df8e64eSIvan Vecera 0x0E96, 68*2df8e64eSIvan Vecera 0x1E96, 69*2df8e64eSIvan Vecera 0x2E96, 70*2df8e64eSIvan Vecera }; 71*2df8e64eSIvan Vecera 72*2df8e64eSIvan Vecera const struct zl3073x_chip_info zl30734_chip_info = { 73*2df8e64eSIvan Vecera .ids = zl30734_ids, 74*2df8e64eSIvan Vecera .num_ids = ARRAY_SIZE(zl30734_ids), 75*2df8e64eSIvan Vecera .num_channels = 4, 76*2df8e64eSIvan Vecera }; 77*2df8e64eSIvan Vecera EXPORT_SYMBOL_NS_GPL(zl30734_chip_info, "ZL3073X"); 78*2df8e64eSIvan Vecera 79*2df8e64eSIvan Vecera /* Chip IDs for zl30735 */ 80*2df8e64eSIvan Vecera static const u16 zl30735_ids[] = { 81*2df8e64eSIvan Vecera 0x0E97, 82*2df8e64eSIvan Vecera 0x1E97, 83*2df8e64eSIvan Vecera 0x2E97, 84*2df8e64eSIvan Vecera }; 85*2df8e64eSIvan Vecera 86*2df8e64eSIvan Vecera const struct zl3073x_chip_info zl30735_chip_info = { 87*2df8e64eSIvan Vecera .ids = zl30735_ids, 88*2df8e64eSIvan Vecera .num_ids = ARRAY_SIZE(zl30735_ids), 89*2df8e64eSIvan Vecera .num_channels = 5, 90*2df8e64eSIvan Vecera }; 91*2df8e64eSIvan Vecera EXPORT_SYMBOL_NS_GPL(zl30735_chip_info, "ZL3073X"); 92*2df8e64eSIvan Vecera 93*2df8e64eSIvan Vecera #define ZL_RANGE_OFFSET 0x80 94*2df8e64eSIvan Vecera #define ZL_PAGE_SIZE 0x80 95*2df8e64eSIvan Vecera #define ZL_NUM_PAGES 15 96*2df8e64eSIvan Vecera #define ZL_PAGE_SEL 0x7F 97*2df8e64eSIvan Vecera #define ZL_PAGE_SEL_MASK GENMASK(3, 0) 98*2df8e64eSIvan Vecera #define ZL_NUM_REGS (ZL_NUM_PAGES * ZL_PAGE_SIZE) 99*2df8e64eSIvan Vecera 100*2df8e64eSIvan Vecera /* Regmap range configuration */ 101*2df8e64eSIvan Vecera static const struct regmap_range_cfg zl3073x_regmap_range = { 102*2df8e64eSIvan Vecera .range_min = ZL_RANGE_OFFSET, 103*2df8e64eSIvan Vecera .range_max = ZL_RANGE_OFFSET + ZL_NUM_REGS - 1, 104*2df8e64eSIvan Vecera .selector_reg = ZL_PAGE_SEL, 105*2df8e64eSIvan Vecera .selector_mask = ZL_PAGE_SEL_MASK, 106*2df8e64eSIvan Vecera .selector_shift = 0, 107*2df8e64eSIvan Vecera .window_start = 0, 108*2df8e64eSIvan Vecera .window_len = ZL_PAGE_SIZE, 109*2df8e64eSIvan Vecera }; 110*2df8e64eSIvan Vecera 111*2df8e64eSIvan Vecera static bool 112*2df8e64eSIvan Vecera zl3073x_is_volatile_reg(struct device *dev __maybe_unused, unsigned int reg) 113*2df8e64eSIvan Vecera { 114*2df8e64eSIvan Vecera /* Only page selector is non-volatile */ 115*2df8e64eSIvan Vecera return reg != ZL_PAGE_SEL; 116*2df8e64eSIvan Vecera } 117*2df8e64eSIvan Vecera 118*2df8e64eSIvan Vecera const struct regmap_config zl3073x_regmap_config = { 119*2df8e64eSIvan Vecera .reg_bits = 8, 120*2df8e64eSIvan Vecera .val_bits = 8, 121*2df8e64eSIvan Vecera .max_register = ZL_RANGE_OFFSET + ZL_NUM_REGS - 1, 122*2df8e64eSIvan Vecera .ranges = &zl3073x_regmap_range, 123*2df8e64eSIvan Vecera .num_ranges = 1, 124*2df8e64eSIvan Vecera .cache_type = REGCACHE_MAPLE, 125*2df8e64eSIvan Vecera .volatile_reg = zl3073x_is_volatile_reg, 126*2df8e64eSIvan Vecera }; 127*2df8e64eSIvan Vecera EXPORT_SYMBOL_NS_GPL(zl3073x_regmap_config, "ZL3073X"); 128*2df8e64eSIvan Vecera 129*2df8e64eSIvan Vecera static bool 130*2df8e64eSIvan Vecera zl3073x_check_reg(struct zl3073x_dev *zldev, unsigned int reg, size_t size) 131*2df8e64eSIvan Vecera { 132*2df8e64eSIvan Vecera /* Check that multiop lock is held when accessing registers 133*2df8e64eSIvan Vecera * from page 10 and above. 134*2df8e64eSIvan Vecera */ 135*2df8e64eSIvan Vecera if (ZL_REG_PAGE(reg) >= 10) 136*2df8e64eSIvan Vecera lockdep_assert_held(&zldev->multiop_lock); 137*2df8e64eSIvan Vecera 138*2df8e64eSIvan Vecera /* Check the index is in valid range for indexed register */ 139*2df8e64eSIvan Vecera if (ZL_REG_OFFSET(reg) > ZL_REG_MAX_OFFSET(reg)) { 140*2df8e64eSIvan Vecera dev_err(zldev->dev, "Index out of range for reg 0x%04lx\n", 141*2df8e64eSIvan Vecera ZL_REG_ADDR(reg)); 142*2df8e64eSIvan Vecera return false; 143*2df8e64eSIvan Vecera } 144*2df8e64eSIvan Vecera /* Check the requested size corresponds to register size */ 145*2df8e64eSIvan Vecera if (ZL_REG_SIZE(reg) != size) { 146*2df8e64eSIvan Vecera dev_err(zldev->dev, "Invalid size %zu for reg 0x%04lx\n", 147*2df8e64eSIvan Vecera size, ZL_REG_ADDR(reg)); 148*2df8e64eSIvan Vecera return false; 149*2df8e64eSIvan Vecera } 150*2df8e64eSIvan Vecera 151*2df8e64eSIvan Vecera return true; 152*2df8e64eSIvan Vecera } 153*2df8e64eSIvan Vecera 154*2df8e64eSIvan Vecera static int 155*2df8e64eSIvan Vecera zl3073x_read_reg(struct zl3073x_dev *zldev, unsigned int reg, void *val, 156*2df8e64eSIvan Vecera size_t size) 157*2df8e64eSIvan Vecera { 158*2df8e64eSIvan Vecera int rc; 159*2df8e64eSIvan Vecera 160*2df8e64eSIvan Vecera if (!zl3073x_check_reg(zldev, reg, size)) 161*2df8e64eSIvan Vecera return -EINVAL; 162*2df8e64eSIvan Vecera 163*2df8e64eSIvan Vecera /* Map the register address to virtual range */ 164*2df8e64eSIvan Vecera reg = ZL_REG_ADDR(reg) + ZL_RANGE_OFFSET; 165*2df8e64eSIvan Vecera 166*2df8e64eSIvan Vecera rc = regmap_bulk_read(zldev->regmap, reg, val, size); 167*2df8e64eSIvan Vecera if (rc) { 168*2df8e64eSIvan Vecera dev_err(zldev->dev, "Failed to read reg 0x%04x: %pe\n", reg, 169*2df8e64eSIvan Vecera ERR_PTR(rc)); 170*2df8e64eSIvan Vecera return rc; 171*2df8e64eSIvan Vecera } 172*2df8e64eSIvan Vecera 173*2df8e64eSIvan Vecera return 0; 174*2df8e64eSIvan Vecera } 175*2df8e64eSIvan Vecera 176*2df8e64eSIvan Vecera static int 177*2df8e64eSIvan Vecera zl3073x_write_reg(struct zl3073x_dev *zldev, unsigned int reg, const void *val, 178*2df8e64eSIvan Vecera size_t size) 179*2df8e64eSIvan Vecera { 180*2df8e64eSIvan Vecera int rc; 181*2df8e64eSIvan Vecera 182*2df8e64eSIvan Vecera if (!zl3073x_check_reg(zldev, reg, size)) 183*2df8e64eSIvan Vecera return -EINVAL; 184*2df8e64eSIvan Vecera 185*2df8e64eSIvan Vecera /* Map the register address to virtual range */ 186*2df8e64eSIvan Vecera reg = ZL_REG_ADDR(reg) + ZL_RANGE_OFFSET; 187*2df8e64eSIvan Vecera 188*2df8e64eSIvan Vecera rc = regmap_bulk_write(zldev->regmap, reg, val, size); 189*2df8e64eSIvan Vecera if (rc) { 190*2df8e64eSIvan Vecera dev_err(zldev->dev, "Failed to write reg 0x%04x: %pe\n", reg, 191*2df8e64eSIvan Vecera ERR_PTR(rc)); 192*2df8e64eSIvan Vecera return rc; 193*2df8e64eSIvan Vecera } 194*2df8e64eSIvan Vecera 195*2df8e64eSIvan Vecera return 0; 196*2df8e64eSIvan Vecera } 197*2df8e64eSIvan Vecera 198*2df8e64eSIvan Vecera /** 199*2df8e64eSIvan Vecera * zl3073x_read_u8 - read value from 8bit register 200*2df8e64eSIvan Vecera * @zldev: zl3073x device pointer 201*2df8e64eSIvan Vecera * @reg: register to write to 202*2df8e64eSIvan Vecera * @val: value to write 203*2df8e64eSIvan Vecera * 204*2df8e64eSIvan Vecera * Reads value from given 8bit register. 205*2df8e64eSIvan Vecera * 206*2df8e64eSIvan Vecera * Returns: 0 on success, <0 on error 207*2df8e64eSIvan Vecera */ 208*2df8e64eSIvan Vecera int zl3073x_read_u8(struct zl3073x_dev *zldev, unsigned int reg, u8 *val) 209*2df8e64eSIvan Vecera { 210*2df8e64eSIvan Vecera return zl3073x_read_reg(zldev, reg, val, sizeof(*val)); 211*2df8e64eSIvan Vecera } 212*2df8e64eSIvan Vecera 213*2df8e64eSIvan Vecera /** 214*2df8e64eSIvan Vecera * zl3073x_write_u8 - write value to 16bit register 215*2df8e64eSIvan Vecera * @zldev: zl3073x device pointer 216*2df8e64eSIvan Vecera * @reg: register to write to 217*2df8e64eSIvan Vecera * @val: value to write 218*2df8e64eSIvan Vecera * 219*2df8e64eSIvan Vecera * Writes value into given 8bit register. 220*2df8e64eSIvan Vecera * 221*2df8e64eSIvan Vecera * Returns: 0 on success, <0 on error 222*2df8e64eSIvan Vecera */ 223*2df8e64eSIvan Vecera int zl3073x_write_u8(struct zl3073x_dev *zldev, unsigned int reg, u8 val) 224*2df8e64eSIvan Vecera { 225*2df8e64eSIvan Vecera return zl3073x_write_reg(zldev, reg, &val, sizeof(val)); 226*2df8e64eSIvan Vecera } 227*2df8e64eSIvan Vecera 228*2df8e64eSIvan Vecera /** 229*2df8e64eSIvan Vecera * zl3073x_read_u16 - read value from 16bit register 230*2df8e64eSIvan Vecera * @zldev: zl3073x device pointer 231*2df8e64eSIvan Vecera * @reg: register to write to 232*2df8e64eSIvan Vecera * @val: value to write 233*2df8e64eSIvan Vecera * 234*2df8e64eSIvan Vecera * Reads value from given 16bit register. 235*2df8e64eSIvan Vecera * 236*2df8e64eSIvan Vecera * Returns: 0 on success, <0 on error 237*2df8e64eSIvan Vecera */ 238*2df8e64eSIvan Vecera int zl3073x_read_u16(struct zl3073x_dev *zldev, unsigned int reg, u16 *val) 239*2df8e64eSIvan Vecera { 240*2df8e64eSIvan Vecera int rc; 241*2df8e64eSIvan Vecera 242*2df8e64eSIvan Vecera rc = zl3073x_read_reg(zldev, reg, val, sizeof(*val)); 243*2df8e64eSIvan Vecera if (!rc) 244*2df8e64eSIvan Vecera be16_to_cpus(val); 245*2df8e64eSIvan Vecera 246*2df8e64eSIvan Vecera return rc; 247*2df8e64eSIvan Vecera } 248*2df8e64eSIvan Vecera 249*2df8e64eSIvan Vecera /** 250*2df8e64eSIvan Vecera * zl3073x_write_u16 - write value to 16bit register 251*2df8e64eSIvan Vecera * @zldev: zl3073x device pointer 252*2df8e64eSIvan Vecera * @reg: register to write to 253*2df8e64eSIvan Vecera * @val: value to write 254*2df8e64eSIvan Vecera * 255*2df8e64eSIvan Vecera * Writes value into given 16bit register. 256*2df8e64eSIvan Vecera * 257*2df8e64eSIvan Vecera * Returns: 0 on success, <0 on error 258*2df8e64eSIvan Vecera */ 259*2df8e64eSIvan Vecera int zl3073x_write_u16(struct zl3073x_dev *zldev, unsigned int reg, u16 val) 260*2df8e64eSIvan Vecera { 261*2df8e64eSIvan Vecera cpu_to_be16s(&val); 262*2df8e64eSIvan Vecera 263*2df8e64eSIvan Vecera return zl3073x_write_reg(zldev, reg, &val, sizeof(val)); 264*2df8e64eSIvan Vecera } 265*2df8e64eSIvan Vecera 266*2df8e64eSIvan Vecera /** 267*2df8e64eSIvan Vecera * zl3073x_read_u32 - read value from 32bit register 268*2df8e64eSIvan Vecera * @zldev: zl3073x device pointer 269*2df8e64eSIvan Vecera * @reg: register to write to 270*2df8e64eSIvan Vecera * @val: value to write 271*2df8e64eSIvan Vecera * 272*2df8e64eSIvan Vecera * Reads value from given 32bit register. 273*2df8e64eSIvan Vecera * 274*2df8e64eSIvan Vecera * Returns: 0 on success, <0 on error 275*2df8e64eSIvan Vecera */ 276*2df8e64eSIvan Vecera int zl3073x_read_u32(struct zl3073x_dev *zldev, unsigned int reg, u32 *val) 277*2df8e64eSIvan Vecera { 278*2df8e64eSIvan Vecera int rc; 279*2df8e64eSIvan Vecera 280*2df8e64eSIvan Vecera rc = zl3073x_read_reg(zldev, reg, val, sizeof(*val)); 281*2df8e64eSIvan Vecera if (!rc) 282*2df8e64eSIvan Vecera be32_to_cpus(val); 283*2df8e64eSIvan Vecera 284*2df8e64eSIvan Vecera return rc; 285*2df8e64eSIvan Vecera } 286*2df8e64eSIvan Vecera 287*2df8e64eSIvan Vecera /** 288*2df8e64eSIvan Vecera * zl3073x_write_u32 - write value to 32bit register 289*2df8e64eSIvan Vecera * @zldev: zl3073x device pointer 290*2df8e64eSIvan Vecera * @reg: register to write to 291*2df8e64eSIvan Vecera * @val: value to write 292*2df8e64eSIvan Vecera * 293*2df8e64eSIvan Vecera * Writes value into given 32bit register. 294*2df8e64eSIvan Vecera * 295*2df8e64eSIvan Vecera * Returns: 0 on success, <0 on error 296*2df8e64eSIvan Vecera */ 297*2df8e64eSIvan Vecera int zl3073x_write_u32(struct zl3073x_dev *zldev, unsigned int reg, u32 val) 298*2df8e64eSIvan Vecera { 299*2df8e64eSIvan Vecera cpu_to_be32s(&val); 300*2df8e64eSIvan Vecera 301*2df8e64eSIvan Vecera return zl3073x_write_reg(zldev, reg, &val, sizeof(val)); 302*2df8e64eSIvan Vecera } 303*2df8e64eSIvan Vecera 304*2df8e64eSIvan Vecera /** 305*2df8e64eSIvan Vecera * zl3073x_read_u48 - read value from 48bit register 306*2df8e64eSIvan Vecera * @zldev: zl3073x device pointer 307*2df8e64eSIvan Vecera * @reg: register to write to 308*2df8e64eSIvan Vecera * @val: value to write 309*2df8e64eSIvan Vecera * 310*2df8e64eSIvan Vecera * Reads value from given 48bit register. 311*2df8e64eSIvan Vecera * 312*2df8e64eSIvan Vecera * Returns: 0 on success, <0 on error 313*2df8e64eSIvan Vecera */ 314*2df8e64eSIvan Vecera int zl3073x_read_u48(struct zl3073x_dev *zldev, unsigned int reg, u64 *val) 315*2df8e64eSIvan Vecera { 316*2df8e64eSIvan Vecera u8 buf[6]; 317*2df8e64eSIvan Vecera int rc; 318*2df8e64eSIvan Vecera 319*2df8e64eSIvan Vecera rc = zl3073x_read_reg(zldev, reg, buf, sizeof(buf)); 320*2df8e64eSIvan Vecera if (!rc) 321*2df8e64eSIvan Vecera *val = get_unaligned_be48(buf); 322*2df8e64eSIvan Vecera 323*2df8e64eSIvan Vecera return rc; 324*2df8e64eSIvan Vecera } 325*2df8e64eSIvan Vecera 326*2df8e64eSIvan Vecera /** 327*2df8e64eSIvan Vecera * zl3073x_write_u48 - write value to 48bit register 328*2df8e64eSIvan Vecera * @zldev: zl3073x device pointer 329*2df8e64eSIvan Vecera * @reg: register to write to 330*2df8e64eSIvan Vecera * @val: value to write 331*2df8e64eSIvan Vecera * 332*2df8e64eSIvan Vecera * Writes value into given 48bit register. 333*2df8e64eSIvan Vecera * The value must be from the interval -S48_MIN to U48_MAX. 334*2df8e64eSIvan Vecera * 335*2df8e64eSIvan Vecera * Returns: 0 on success, <0 on error 336*2df8e64eSIvan Vecera */ 337*2df8e64eSIvan Vecera int zl3073x_write_u48(struct zl3073x_dev *zldev, unsigned int reg, u64 val) 338*2df8e64eSIvan Vecera { 339*2df8e64eSIvan Vecera u8 buf[6]; 340*2df8e64eSIvan Vecera 341*2df8e64eSIvan Vecera /* Check the value belongs to <S48_MIN, U48_MAX> 342*2df8e64eSIvan Vecera * Any value >= S48_MIN has bits 47..63 set. 343*2df8e64eSIvan Vecera */ 344*2df8e64eSIvan Vecera if (val > GENMASK_ULL(47, 0) && val < GENMASK_ULL(63, 47)) { 345*2df8e64eSIvan Vecera dev_err(zldev->dev, "Value 0x%0llx out of range\n", val); 346*2df8e64eSIvan Vecera return -EINVAL; 347*2df8e64eSIvan Vecera } 348*2df8e64eSIvan Vecera 349*2df8e64eSIvan Vecera put_unaligned_be48(val, buf); 350*2df8e64eSIvan Vecera 351*2df8e64eSIvan Vecera return zl3073x_write_reg(zldev, reg, buf, sizeof(buf)); 352*2df8e64eSIvan Vecera } 353*2df8e64eSIvan Vecera 354*2df8e64eSIvan Vecera /** 355*2df8e64eSIvan Vecera * zl3073x_poll_zero_u8 - wait for register to be cleared by device 356*2df8e64eSIvan Vecera * @zldev: zl3073x device pointer 357*2df8e64eSIvan Vecera * @reg: register to poll (has to be 8bit register) 358*2df8e64eSIvan Vecera * @mask: bit mask for polling 359*2df8e64eSIvan Vecera * 360*2df8e64eSIvan Vecera * Waits for bits specified by @mask in register @reg value to be cleared 361*2df8e64eSIvan Vecera * by the device. 362*2df8e64eSIvan Vecera * 363*2df8e64eSIvan Vecera * Returns: 0 on success, <0 on error 364*2df8e64eSIvan Vecera */ 365*2df8e64eSIvan Vecera int zl3073x_poll_zero_u8(struct zl3073x_dev *zldev, unsigned int reg, u8 mask) 366*2df8e64eSIvan Vecera { 367*2df8e64eSIvan Vecera /* Register polling sleep & timeout */ 368*2df8e64eSIvan Vecera #define ZL_POLL_SLEEP_US 10 369*2df8e64eSIvan Vecera #define ZL_POLL_TIMEOUT_US 2000000 370*2df8e64eSIvan Vecera unsigned int val; 371*2df8e64eSIvan Vecera 372*2df8e64eSIvan Vecera /* Check the register is 8bit */ 373*2df8e64eSIvan Vecera if (ZL_REG_SIZE(reg) != 1) { 374*2df8e64eSIvan Vecera dev_err(zldev->dev, "Invalid reg 0x%04lx size for polling\n", 375*2df8e64eSIvan Vecera ZL_REG_ADDR(reg)); 376*2df8e64eSIvan Vecera return -EINVAL; 377*2df8e64eSIvan Vecera } 378*2df8e64eSIvan Vecera 379*2df8e64eSIvan Vecera /* Map the register address to virtual range */ 380*2df8e64eSIvan Vecera reg = ZL_REG_ADDR(reg) + ZL_RANGE_OFFSET; 381*2df8e64eSIvan Vecera 382*2df8e64eSIvan Vecera return regmap_read_poll_timeout(zldev->regmap, reg, val, !(val & mask), 383*2df8e64eSIvan Vecera ZL_POLL_SLEEP_US, ZL_POLL_TIMEOUT_US); 384*2df8e64eSIvan Vecera } 385*2df8e64eSIvan Vecera 386*2df8e64eSIvan Vecera /** 387*2df8e64eSIvan Vecera * zl3073x_dev_probe - initialize zl3073x device 388*2df8e64eSIvan Vecera * @zldev: pointer to zl3073x device 389*2df8e64eSIvan Vecera * @chip_info: chip info based on compatible 390*2df8e64eSIvan Vecera * 391*2df8e64eSIvan Vecera * Common initialization of zl3073x device structure. 392*2df8e64eSIvan Vecera * 393*2df8e64eSIvan Vecera * Returns: 0 on success, <0 on error 394*2df8e64eSIvan Vecera */ 395*2df8e64eSIvan Vecera int zl3073x_dev_probe(struct zl3073x_dev *zldev, 396*2df8e64eSIvan Vecera const struct zl3073x_chip_info *chip_info) 397*2df8e64eSIvan Vecera { 398*2df8e64eSIvan Vecera u16 id, revision, fw_ver; 399*2df8e64eSIvan Vecera unsigned int i; 400*2df8e64eSIvan Vecera u32 cfg_ver; 401*2df8e64eSIvan Vecera int rc; 402*2df8e64eSIvan Vecera 403*2df8e64eSIvan Vecera /* Read chip ID */ 404*2df8e64eSIvan Vecera rc = zl3073x_read_u16(zldev, ZL_REG_ID, &id); 405*2df8e64eSIvan Vecera if (rc) 406*2df8e64eSIvan Vecera return rc; 407*2df8e64eSIvan Vecera 408*2df8e64eSIvan Vecera /* Check it matches */ 409*2df8e64eSIvan Vecera for (i = 0; i < chip_info->num_ids; i++) { 410*2df8e64eSIvan Vecera if (id == chip_info->ids[i]) 411*2df8e64eSIvan Vecera break; 412*2df8e64eSIvan Vecera } 413*2df8e64eSIvan Vecera 414*2df8e64eSIvan Vecera if (i == chip_info->num_ids) { 415*2df8e64eSIvan Vecera return dev_err_probe(zldev->dev, -ENODEV, 416*2df8e64eSIvan Vecera "Unknown or non-match chip ID: 0x%0x\n", 417*2df8e64eSIvan Vecera id); 418*2df8e64eSIvan Vecera } 419*2df8e64eSIvan Vecera 420*2df8e64eSIvan Vecera /* Read revision, firmware version and custom config version */ 421*2df8e64eSIvan Vecera rc = zl3073x_read_u16(zldev, ZL_REG_REVISION, &revision); 422*2df8e64eSIvan Vecera if (rc) 423*2df8e64eSIvan Vecera return rc; 424*2df8e64eSIvan Vecera rc = zl3073x_read_u16(zldev, ZL_REG_FW_VER, &fw_ver); 425*2df8e64eSIvan Vecera if (rc) 426*2df8e64eSIvan Vecera return rc; 427*2df8e64eSIvan Vecera rc = zl3073x_read_u32(zldev, ZL_REG_CUSTOM_CONFIG_VER, &cfg_ver); 428*2df8e64eSIvan Vecera if (rc) 429*2df8e64eSIvan Vecera return rc; 430*2df8e64eSIvan Vecera 431*2df8e64eSIvan Vecera dev_dbg(zldev->dev, "ChipID(%X), ChipRev(%X), FwVer(%u)\n", id, 432*2df8e64eSIvan Vecera revision, fw_ver); 433*2df8e64eSIvan Vecera dev_dbg(zldev->dev, "Custom config version: %lu.%lu.%lu.%lu\n", 434*2df8e64eSIvan Vecera FIELD_GET(GENMASK(31, 24), cfg_ver), 435*2df8e64eSIvan Vecera FIELD_GET(GENMASK(23, 16), cfg_ver), 436*2df8e64eSIvan Vecera FIELD_GET(GENMASK(15, 8), cfg_ver), 437*2df8e64eSIvan Vecera FIELD_GET(GENMASK(7, 0), cfg_ver)); 438*2df8e64eSIvan Vecera 439*2df8e64eSIvan Vecera /* Generate random clock ID as the device has not such property that 440*2df8e64eSIvan Vecera * could be used for this purpose. A user can later change this value 441*2df8e64eSIvan Vecera * using devlink. 442*2df8e64eSIvan Vecera */ 443*2df8e64eSIvan Vecera zldev->clock_id = get_random_u64(); 444*2df8e64eSIvan Vecera 445*2df8e64eSIvan Vecera /* Initialize mutex for operations where multiple reads, writes 446*2df8e64eSIvan Vecera * and/or polls are required to be done atomically. 447*2df8e64eSIvan Vecera */ 448*2df8e64eSIvan Vecera rc = devm_mutex_init(zldev->dev, &zldev->multiop_lock); 449*2df8e64eSIvan Vecera if (rc) 450*2df8e64eSIvan Vecera return dev_err_probe(zldev->dev, rc, 451*2df8e64eSIvan Vecera "Failed to initialize mutex\n"); 452*2df8e64eSIvan Vecera 453*2df8e64eSIvan Vecera /* Register the devlink instance and parameters */ 454*2df8e64eSIvan Vecera rc = zl3073x_devlink_register(zldev); 455*2df8e64eSIvan Vecera if (rc) 456*2df8e64eSIvan Vecera return dev_err_probe(zldev->dev, rc, 457*2df8e64eSIvan Vecera "Failed to register devlink instance\n"); 458*2df8e64eSIvan Vecera 459*2df8e64eSIvan Vecera return 0; 460*2df8e64eSIvan Vecera } 461*2df8e64eSIvan Vecera EXPORT_SYMBOL_NS_GPL(zl3073x_dev_probe, "ZL3073X"); 462*2df8e64eSIvan Vecera 463*2df8e64eSIvan Vecera MODULE_AUTHOR("Ivan Vecera <ivecera@redhat.com>"); 464*2df8e64eSIvan Vecera MODULE_DESCRIPTION("Microchip ZL3073x core driver"); 465*2df8e64eSIvan Vecera MODULE_LICENSE("GPL"); 466