@@ -461,7 +461,7 @@ static const struct regmap_range_cfg spd5118_i2c_regmap_range_cfg[] = {
461461 },
462462};
463463
464- static const struct regmap_config spd5118_i2c_regmap_config = {
464+ static const struct regmap_config spd5118_regmap8_config = {
465465 .reg_bits = 8 ,
466466 .val_bits = 8 ,
467467 .max_register = 0x7ff ,
@@ -473,6 +473,15 @@ static const struct regmap_config spd5118_i2c_regmap_config = {
473473 .num_ranges = ARRAY_SIZE (spd5118_i2c_regmap_range_cfg ),
474474};
475475
476+ static const struct regmap_config spd5118_regmap16_config = {
477+ .reg_bits = 16 ,
478+ .val_bits = 8 ,
479+ .max_register = 0x7ff ,
480+ .writeable_reg = spd5118_writeable_reg ,
481+ .volatile_reg = spd5118_volatile_reg ,
482+ .cache_type = REGCACHE_MAPLE ,
483+ };
484+
476485static int spd5118_suspend (struct device * dev )
477486{
478487 struct spd5118_data * data = dev_get_drvdata (dev );
@@ -510,7 +519,8 @@ static int spd5118_resume(struct device *dev)
510519
511520static DEFINE_SIMPLE_DEV_PM_OPS (spd5118_pm_ops , spd5118_suspend , spd5118_resume ) ;
512521
513- static int spd5118_common_probe (struct device * dev , struct regmap * regmap )
522+ static int spd5118_common_probe (struct device * dev , struct regmap * regmap ,
523+ bool is_16bit )
514524{
515525 unsigned int capability , revision , vendor , bank ;
516526 struct spd5118_data * data ;
@@ -527,12 +537,7 @@ static int spd5118_common_probe(struct device *dev, struct regmap *regmap)
527537 if (!(capability & SPD5118_CAP_TS_SUPPORT ))
528538 return - ENODEV ;
529539
530- /*
531- * 16-bit register addresses are not (yet) supported with I2C.
532- * Therefore, if this is an I2C device, register addresses must be
533- * 8 bit wide.
534- */
535- data -> is_16bit = !!i2c_verify_adapter (dev );
540+ data -> is_16bit = is_16bit ;
536541
537542 err = regmap_read (regmap , SPD5118_REG_REVISION , & revision );
538543 if (err )
@@ -675,21 +680,69 @@ static int spd5118_i2c_init(struct i2c_client *client)
675680 return 0 ;
676681}
677682
683+ /*
684+ * 16-bit addressing note:
685+ *
686+ * If I2C_FUNC_I2C is not supported by an I2C adapter driver, regmap uses
687+ * SMBus operations as alternative. To simulate a read operation with a 16-bit
688+ * address, it writes the address using i2c_smbus_write_byte_data(), followed
689+ * by one or more calls to i2c_smbus_read_byte() to read the data.
690+ * Per spd5118 standard, a read operation after writing the address must start
691+ * with <Sr> (Repeat Start). However, a SMBus read byte operation starts with
692+ * <S> (Start). This resets the register address in the spd5118 chip. As result,
693+ * i2c_smbus_read_byte() always returns data from register address 0x00.
694+ *
695+ * A working alternative to access chips with 16-bit register addresses in the
696+ * absence of I2C_FUNC_I2C support is not known.
697+ *
698+ * For this reason, 16-bit addressing can only be supported with I2C if the
699+ * adapter supports I2C_FUNC_I2C.
700+ *
701+ * For I2C, the addressing mode selected by the BIOS must not be changed.
702+ * Experiments show that at least some PC BIOS versions will not change the
703+ * addressing mode on a soft reboot and end up in setup, claiming that some
704+ * configuration change happened. This will happen again after a power cycle,
705+ * which does reset the addressing mode. To prevent this from happening,
706+ * detect if 16-bit addressing is enabled and always use the currently
707+ * configured addressing mode.
708+ */
709+
678710static int spd5118_i2c_probe (struct i2c_client * client )
679711{
712+ const struct regmap_config * config ;
680713 struct device * dev = & client -> dev ;
681714 struct regmap * regmap ;
682- int err ;
715+ int err , mode ;
716+ bool is_16bit ;
683717
684718 err = spd5118_i2c_init (client );
685719 if (err )
686720 return err ;
687721
688- regmap = devm_regmap_init_i2c (client , & spd5118_i2c_regmap_config );
722+ mode = i2c_smbus_read_byte_data (client , SPD5118_REG_I2C_LEGACY_MODE );
723+ if (mode < 0 )
724+ return mode ;
725+
726+ is_16bit = mode & SPD5118_LEGACY_MODE_ADDR ;
727+ if (is_16bit ) {
728+ /*
729+ * See 16-bit addressing note above explaining why it is
730+ * necessary to check for I2C_FUNC_I2C support here.
731+ */
732+ if (!i2c_check_functionality (client -> adapter , I2C_FUNC_I2C )) {
733+ dev_err (dev , "Adapter does not support 16-bit register addresses\n" );
734+ return - ENODEV ;
735+ }
736+ config = & spd5118_regmap16_config ;
737+ } else {
738+ config = & spd5118_regmap8_config ;
739+ }
740+
741+ regmap = devm_regmap_init_i2c (client , config );
689742 if (IS_ERR (regmap ))
690743 return dev_err_probe (dev , PTR_ERR (regmap ), "regmap init failed\n" );
691744
692- return spd5118_common_probe (dev , regmap );
745+ return spd5118_common_probe (dev , regmap , is_16bit );
693746}
694747
695748static const struct i2c_device_id spd5118_i2c_id [] = {
0 commit comments