Skip to content

Commit 4cf1aab

Browse files
committed
hwmon: (spd5118) Split into common and I2C specific code
Split spd5118 driver into common and I2C specific code to enable adding support for I3C. Signed-off-by: Guenter Roeck <[email protected]>
1 parent e799657 commit 4cf1aab

File tree

1 file changed

+143
-134
lines changed

1 file changed

+143
-134
lines changed

drivers/hwmon/spd5118.c

Lines changed: 143 additions & 134 deletions
Original file line numberDiff line numberDiff line change
@@ -305,51 +305,6 @@ static bool spd5118_vendor_valid(u8 bank, u8 id)
305305
return id && id != 0x7f;
306306
}
307307

308-
/* Return 0 if detection is successful, -ENODEV otherwise */
309-
static int spd5118_detect(struct i2c_client *client, struct i2c_board_info *info)
310-
{
311-
struct i2c_adapter *adapter = client->adapter;
312-
int regval;
313-
314-
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
315-
I2C_FUNC_SMBUS_WORD_DATA))
316-
return -ENODEV;
317-
318-
regval = i2c_smbus_read_word_swapped(client, SPD5118_REG_TYPE);
319-
if (regval != 0x5118)
320-
return -ENODEV;
321-
322-
regval = i2c_smbus_read_word_data(client, SPD5118_REG_VENDOR);
323-
if (regval < 0 || !spd5118_vendor_valid(regval & 0xff, regval >> 8))
324-
return -ENODEV;
325-
326-
regval = i2c_smbus_read_byte_data(client, SPD5118_REG_CAPABILITY);
327-
if (regval < 0)
328-
return -ENODEV;
329-
if (!(regval & SPD5118_CAP_TS_SUPPORT) || (regval & 0xfc))
330-
return -ENODEV;
331-
332-
regval = i2c_smbus_read_byte_data(client, SPD5118_REG_TEMP_CLR);
333-
if (regval)
334-
return -ENODEV;
335-
regval = i2c_smbus_read_byte_data(client, SPD5118_REG_ERROR_CLR);
336-
if (regval)
337-
return -ENODEV;
338-
339-
regval = i2c_smbus_read_byte_data(client, SPD5118_REG_REVISION);
340-
if (regval < 0 || (regval & 0xc1))
341-
return -ENODEV;
342-
343-
regval = i2c_smbus_read_byte_data(client, SPD5118_REG_TEMP_CONFIG);
344-
if (regval < 0)
345-
return -ENODEV;
346-
if (regval & ~SPD5118_TS_DISABLE)
347-
return -ENODEV;
348-
349-
strscpy(info->type, "spd5118", I2C_NAME_SIZE);
350-
return 0;
351-
}
352-
353308
static const struct hwmon_channel_info *spd5118_info[] = {
354309
HWMON_CHANNEL_INFO(chip,
355310
HWMON_C_REGISTER_TZ),
@@ -483,7 +438,7 @@ static bool spd5118_volatile_reg(struct device *dev, unsigned int reg)
483438
}
484439
}
485440

486-
static const struct regmap_range_cfg spd5118_regmap_range_cfg[] = {
441+
static const struct regmap_range_cfg spd5118_i2c_regmap_range_cfg[] = {
487442
{
488443
.selector_reg = SPD5118_REG_I2C_LEGACY_MODE,
489444
.selector_mask = SPD5118_LEGACY_PAGE_MASK,
@@ -495,95 +450,70 @@ static const struct regmap_range_cfg spd5118_regmap_range_cfg[] = {
495450
},
496451
};
497452

498-
static const struct regmap_config spd5118_regmap_config = {
453+
static const struct regmap_config spd5118_i2c_regmap_config = {
499454
.reg_bits = 8,
500455
.val_bits = 8,
501456
.max_register = 0x7ff,
502457
.writeable_reg = spd5118_writeable_reg,
503458
.volatile_reg = spd5118_volatile_reg,
504459
.cache_type = REGCACHE_MAPLE,
505460

506-
.ranges = spd5118_regmap_range_cfg,
507-
.num_ranges = ARRAY_SIZE(spd5118_regmap_range_cfg),
461+
.ranges = spd5118_i2c_regmap_range_cfg,
462+
.num_ranges = ARRAY_SIZE(spd5118_i2c_regmap_range_cfg),
508463
};
509464

510-
static int spd5118_init(struct i2c_client *client)
465+
static int spd5118_suspend(struct device *dev)
511466
{
512-
struct i2c_adapter *adapter = client->adapter;
513-
int err, regval, mode;
514-
515-
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
516-
I2C_FUNC_SMBUS_WORD_DATA))
517-
return -ENODEV;
518-
519-
regval = i2c_smbus_read_word_swapped(client, SPD5118_REG_TYPE);
520-
if (regval < 0 || (regval && regval != 0x5118))
521-
return -ENODEV;
467+
struct spd5118_data *data = dev_get_drvdata(dev);
468+
struct regmap *regmap = data->regmap;
469+
u32 regval;
470+
int err;
522471

523472
/*
524-
* If the device type registers return 0, it is possible that the chip
525-
* has a non-zero page selected and takes the specification literally,
526-
* i.e. disables access to volatile registers besides the page register
527-
* if the page is not 0. Try to identify such chips.
473+
* Make sure the configuration register in the regmap cache is current
474+
* before bypassing it.
528475
*/
529-
if (!regval) {
530-
/* Vendor ID registers must also be 0 */
531-
regval = i2c_smbus_read_word_data(client, SPD5118_REG_VENDOR);
532-
if (regval)
533-
return -ENODEV;
534-
535-
/* The selected page in MR11 must not be 0 */
536-
mode = i2c_smbus_read_byte_data(client, SPD5118_REG_I2C_LEGACY_MODE);
537-
if (mode < 0 || (mode & ~SPD5118_LEGACY_MODE_MASK) ||
538-
!(mode & SPD5118_LEGACY_PAGE_MASK))
539-
return -ENODEV;
476+
err = regmap_read(regmap, SPD5118_REG_TEMP_CONFIG, &regval);
477+
if (err < 0)
478+
return err;
540479

541-
err = i2c_smbus_write_byte_data(client, SPD5118_REG_I2C_LEGACY_MODE,
542-
mode & SPD5118_LEGACY_MODE_ADDR);
543-
if (err)
544-
return -ENODEV;
480+
regcache_cache_bypass(regmap, true);
481+
regmap_update_bits(regmap, SPD5118_REG_TEMP_CONFIG, SPD5118_TS_DISABLE,
482+
SPD5118_TS_DISABLE);
483+
regcache_cache_bypass(regmap, false);
545484

546-
/*
547-
* If the device type registers are still bad after selecting
548-
* page 0, this is not a SPD5118 device. Restore original
549-
* legacy mode register value and abort.
550-
*/
551-
regval = i2c_smbus_read_word_swapped(client, SPD5118_REG_TYPE);
552-
if (regval != 0x5118) {
553-
i2c_smbus_write_byte_data(client, SPD5118_REG_I2C_LEGACY_MODE, mode);
554-
return -ENODEV;
555-
}
556-
}
485+
regcache_cache_only(regmap, true);
486+
regcache_mark_dirty(regmap);
557487

558-
/* We are reasonably sure that this is really a SPD5118 hub controller */
559488
return 0;
560489
}
561490

562-
static int spd5118_probe(struct i2c_client *client)
491+
static int spd5118_resume(struct device *dev)
563492
{
564-
struct device *dev = &client->dev;
565-
unsigned int regval, revision, vendor, bank;
493+
struct spd5118_data *data = dev_get_drvdata(dev);
494+
struct regmap *regmap = data->regmap;
495+
496+
regcache_cache_only(regmap, false);
497+
return regcache_sync(regmap);
498+
}
499+
500+
static DEFINE_SIMPLE_DEV_PM_OPS(spd5118_pm_ops, spd5118_suspend, spd5118_resume);
501+
502+
static int spd5118_common_probe(struct device *dev, struct regmap *regmap)
503+
{
504+
unsigned int capability, revision, vendor, bank;
566505
struct spd5118_data *data;
567506
struct device *hwmon_dev;
568-
struct regmap *regmap;
569507
int err;
570508

571-
err = spd5118_init(client);
572-
if (err)
573-
return err;
574-
575509
data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
576510
if (!data)
577511
return -ENOMEM;
578512

579-
regmap = devm_regmap_init_i2c(client, &spd5118_regmap_config);
580-
if (IS_ERR(regmap))
581-
return dev_err_probe(dev, PTR_ERR(regmap), "regmap init failed\n");
582-
583-
err = regmap_read(regmap, SPD5118_REG_CAPABILITY, &regval);
513+
err = regmap_read(regmap, SPD5118_REG_CAPABILITY, &capability);
584514
if (err)
585515
return err;
586-
if (!(regval & SPD5118_CAP_TS_SUPPORT))
516+
if (!(capability & SPD5118_CAP_TS_SUPPORT))
587517
return -ENODEV;
588518

589519
err = regmap_read(regmap, SPD5118_REG_REVISION, &revision);
@@ -627,69 +557,148 @@ static int spd5118_probe(struct i2c_client *client)
627557
return 0;
628558
}
629559

630-
static int spd5118_suspend(struct device *dev)
560+
/* I2C */
561+
562+
/* Return 0 if detection is successful, -ENODEV otherwise */
563+
static int spd5118_detect(struct i2c_client *client, struct i2c_board_info *info)
631564
{
632-
struct spd5118_data *data = dev_get_drvdata(dev);
633-
struct regmap *regmap = data->regmap;
634-
u32 regval;
635-
int err;
565+
struct i2c_adapter *adapter = client->adapter;
566+
int regval;
567+
568+
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
569+
I2C_FUNC_SMBUS_WORD_DATA))
570+
return -ENODEV;
571+
572+
regval = i2c_smbus_read_word_swapped(client, SPD5118_REG_TYPE);
573+
if (regval != 0x5118)
574+
return -ENODEV;
575+
576+
regval = i2c_smbus_read_word_data(client, SPD5118_REG_VENDOR);
577+
if (regval < 0 || !spd5118_vendor_valid(regval & 0xff, regval >> 8))
578+
return -ENODEV;
579+
580+
regval = i2c_smbus_read_byte_data(client, SPD5118_REG_CAPABILITY);
581+
if (regval < 0)
582+
return -ENODEV;
583+
if (!(regval & SPD5118_CAP_TS_SUPPORT) || (regval & 0xfc))
584+
return -ENODEV;
585+
586+
regval = i2c_smbus_read_byte_data(client, SPD5118_REG_TEMP_CLR);
587+
if (regval)
588+
return -ENODEV;
589+
regval = i2c_smbus_read_byte_data(client, SPD5118_REG_ERROR_CLR);
590+
if (regval)
591+
return -ENODEV;
592+
593+
regval = i2c_smbus_read_byte_data(client, SPD5118_REG_REVISION);
594+
if (regval < 0 || (regval & 0xc1))
595+
return -ENODEV;
596+
597+
regval = i2c_smbus_read_byte_data(client, SPD5118_REG_TEMP_CONFIG);
598+
if (regval < 0)
599+
return -ENODEV;
600+
if (regval & ~SPD5118_TS_DISABLE)
601+
return -ENODEV;
602+
603+
strscpy(info->type, "spd5118", I2C_NAME_SIZE);
604+
return 0;
605+
}
606+
607+
static int spd5118_i2c_init(struct i2c_client *client)
608+
{
609+
struct i2c_adapter *adapter = client->adapter;
610+
int err, regval, mode;
611+
612+
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
613+
I2C_FUNC_SMBUS_WORD_DATA))
614+
return -ENODEV;
615+
616+
regval = i2c_smbus_read_word_swapped(client, SPD5118_REG_TYPE);
617+
if (regval < 0 || (regval && regval != 0x5118))
618+
return -ENODEV;
636619

637620
/*
638-
* Make sure the configuration register in the regmap cache is current
639-
* before bypassing it.
621+
* If the device type registers return 0, it is possible that the chip
622+
* has a non-zero page selected and takes the specification literally,
623+
* i.e. disables access to volatile registers besides the page register
624+
* if the page is not 0. Try to identify such chips.
640625
*/
641-
err = regmap_read(regmap, SPD5118_REG_TEMP_CONFIG, &regval);
642-
if (err < 0)
643-
return err;
626+
if (!regval) {
627+
/* Vendor ID registers must also be 0 */
628+
regval = i2c_smbus_read_word_data(client, SPD5118_REG_VENDOR);
629+
if (regval)
630+
return -ENODEV;
644631

645-
regcache_cache_bypass(regmap, true);
646-
regmap_update_bits(regmap, SPD5118_REG_TEMP_CONFIG, SPD5118_TS_DISABLE,
647-
SPD5118_TS_DISABLE);
648-
regcache_cache_bypass(regmap, false);
632+
/* The selected page in MR11 must not be 0 */
633+
mode = i2c_smbus_read_byte_data(client, SPD5118_REG_I2C_LEGACY_MODE);
634+
if (mode < 0 || (mode & ~SPD5118_LEGACY_MODE_MASK) ||
635+
!(mode & SPD5118_LEGACY_PAGE_MASK))
636+
return -ENODEV;
649637

650-
regcache_cache_only(regmap, true);
651-
regcache_mark_dirty(regmap);
638+
err = i2c_smbus_write_byte_data(client, SPD5118_REG_I2C_LEGACY_MODE,
639+
mode & SPD5118_LEGACY_MODE_ADDR);
640+
if (err)
641+
return -ENODEV;
652642

643+
/*
644+
* If the device type registers are still bad after selecting
645+
* page 0, this is not a SPD5118 device. Restore original
646+
* legacy mode register value and abort.
647+
*/
648+
regval = i2c_smbus_read_word_swapped(client, SPD5118_REG_TYPE);
649+
if (regval != 0x5118) {
650+
i2c_smbus_write_byte_data(client, SPD5118_REG_I2C_LEGACY_MODE, mode);
651+
return -ENODEV;
652+
}
653+
}
654+
655+
/* We are reasonably sure that this is really a SPD5118 hub controller */
653656
return 0;
654657
}
655658

656-
static int spd5118_resume(struct device *dev)
659+
static int spd5118_i2c_probe(struct i2c_client *client)
657660
{
658-
struct spd5118_data *data = dev_get_drvdata(dev);
659-
struct regmap *regmap = data->regmap;
661+
struct device *dev = &client->dev;
662+
struct regmap *regmap;
663+
int err;
660664

661-
regcache_cache_only(regmap, false);
662-
return regcache_sync(regmap);
663-
}
665+
err = spd5118_i2c_init(client);
666+
if (err)
667+
return err;
664668

665-
static DEFINE_SIMPLE_DEV_PM_OPS(spd5118_pm_ops, spd5118_suspend, spd5118_resume);
669+
regmap = devm_regmap_init_i2c(client, &spd5118_i2c_regmap_config);
670+
if (IS_ERR(regmap))
671+
return dev_err_probe(dev, PTR_ERR(regmap), "regmap init failed\n");
672+
673+
return spd5118_common_probe(dev, regmap);
674+
}
666675

667-
static const struct i2c_device_id spd5118_id[] = {
676+
static const struct i2c_device_id spd5118_i2c_id[] = {
668677
{ "spd5118" },
669678
{ }
670679
};
671-
MODULE_DEVICE_TABLE(i2c, spd5118_id);
680+
MODULE_DEVICE_TABLE(i2c, spd5118_i2c_id);
672681

673682
static const struct of_device_id spd5118_of_ids[] = {
674683
{ .compatible = "jedec,spd5118", },
675684
{ }
676685
};
677686
MODULE_DEVICE_TABLE(of, spd5118_of_ids);
678687

679-
static struct i2c_driver spd5118_driver = {
688+
static struct i2c_driver spd5118_i2c_driver = {
680689
.class = I2C_CLASS_HWMON,
681690
.driver = {
682691
.name = "spd5118",
683692
.of_match_table = spd5118_of_ids,
684693
.pm = pm_sleep_ptr(&spd5118_pm_ops),
685694
},
686-
.probe = spd5118_probe,
687-
.id_table = spd5118_id,
695+
.probe = spd5118_i2c_probe,
696+
.id_table = spd5118_i2c_id,
688697
.detect = IS_ENABLED(CONFIG_SENSORS_SPD5118_DETECT) ? spd5118_detect : NULL,
689698
.address_list = IS_ENABLED(CONFIG_SENSORS_SPD5118_DETECT) ? normal_i2c : NULL,
690699
};
691700

692-
module_i2c_driver(spd5118_driver);
701+
module_i2c_driver(spd5118_i2c_driver);
693702

694703
MODULE_AUTHOR("René Rebe <[email protected]>");
695704
MODULE_AUTHOR("Guenter Roeck <[email protected]>");

0 commit comments

Comments
 (0)