1*c924ee25SMaxime Ripard // SPDX-License-Identifier: GPL-2.0+ 2*c924ee25SMaxime Ripard /* 3*c924ee25SMaxime Ripard * 4*c924ee25SMaxime Ripard * Copyright (c) 2015 Free Electrons 5*c924ee25SMaxime Ripard * Copyright (c) 2015 NextThing Co. 6*c924ee25SMaxime Ripard * Copyright (c) 2018 Microchip Technology, Inc. 7*c924ee25SMaxime Ripard * 8*c924ee25SMaxime Ripard * Maxime Ripard <maxime.ripard@free-electrons.com> 9*c924ee25SMaxime Ripard * Eugen Hristev <eugen.hristev@microchip.com> 10*c924ee25SMaxime Ripard * 11*c924ee25SMaxime Ripard */ 12*c924ee25SMaxime Ripard 13*c924ee25SMaxime Ripard #include <common.h> 14*c924ee25SMaxime Ripard #include <dm.h> 15*c924ee25SMaxime Ripard #include <w1.h> 16*c924ee25SMaxime Ripard #include <w1-eeprom.h> 17*c924ee25SMaxime Ripard 18*c924ee25SMaxime Ripard #include <dm/device-internal.h> 19*c924ee25SMaxime Ripard 20*c924ee25SMaxime Ripard int w1_eeprom_read_buf(struct udevice *dev, unsigned int offset, 21*c924ee25SMaxime Ripard u8 *buf, unsigned int count) 22*c924ee25SMaxime Ripard { 23*c924ee25SMaxime Ripard const struct w1_eeprom_ops *ops = device_get_ops(dev); 24*c924ee25SMaxime Ripard u64 id = 0; 25*c924ee25SMaxime Ripard int ret; 26*c924ee25SMaxime Ripard 27*c924ee25SMaxime Ripard if (!ops->read_buf) 28*c924ee25SMaxime Ripard return -ENOSYS; 29*c924ee25SMaxime Ripard 30*c924ee25SMaxime Ripard ret = w1_eeprom_get_id(dev, &id); 31*c924ee25SMaxime Ripard if (ret) 32*c924ee25SMaxime Ripard return ret; 33*c924ee25SMaxime Ripard if (!id) 34*c924ee25SMaxime Ripard return -ENODEV; 35*c924ee25SMaxime Ripard 36*c924ee25SMaxime Ripard return ops->read_buf(dev, offset, buf, count); 37*c924ee25SMaxime Ripard } 38*c924ee25SMaxime Ripard 39*c924ee25SMaxime Ripard int w1_eeprom_register_new_device(u64 id) 40*c924ee25SMaxime Ripard { 41*c924ee25SMaxime Ripard u8 family = id & 0xff; 42*c924ee25SMaxime Ripard int ret; 43*c924ee25SMaxime Ripard struct udevice *dev; 44*c924ee25SMaxime Ripard 45*c924ee25SMaxime Ripard for (ret = uclass_first_device(UCLASS_W1_EEPROM, &dev); 46*c924ee25SMaxime Ripard !ret && dev; 47*c924ee25SMaxime Ripard uclass_next_device(&dev)) { 48*c924ee25SMaxime Ripard if (ret || !dev) { 49*c924ee25SMaxime Ripard debug("cannot find w1 eeprom dev\n"); 50*c924ee25SMaxime Ripard return ret; 51*c924ee25SMaxime Ripard } 52*c924ee25SMaxime Ripard if (dev_get_driver_data(dev) == family) { 53*c924ee25SMaxime Ripard struct w1_device *w1; 54*c924ee25SMaxime Ripard 55*c924ee25SMaxime Ripard w1 = dev_get_parent_platdata(dev); 56*c924ee25SMaxime Ripard if (w1->id) /* device already in use */ 57*c924ee25SMaxime Ripard continue; 58*c924ee25SMaxime Ripard w1->id = id; 59*c924ee25SMaxime Ripard debug("%s: Match found: %s:%s %llx\n", __func__, 60*c924ee25SMaxime Ripard dev->name, dev->driver->name, id); 61*c924ee25SMaxime Ripard return 0; 62*c924ee25SMaxime Ripard } 63*c924ee25SMaxime Ripard } 64*c924ee25SMaxime Ripard 65*c924ee25SMaxime Ripard debug("%s: No matches found: error %d\n", __func__, ret); 66*c924ee25SMaxime Ripard 67*c924ee25SMaxime Ripard return ret; 68*c924ee25SMaxime Ripard } 69*c924ee25SMaxime Ripard 70*c924ee25SMaxime Ripard int w1_eeprom_get_id(struct udevice *dev, u64 *id) 71*c924ee25SMaxime Ripard { 72*c924ee25SMaxime Ripard struct w1_device *w1 = dev_get_parent_platdata(dev); 73*c924ee25SMaxime Ripard 74*c924ee25SMaxime Ripard if (!w1) 75*c924ee25SMaxime Ripard return -ENODEV; 76*c924ee25SMaxime Ripard *id = w1->id; 77*c924ee25SMaxime Ripard 78*c924ee25SMaxime Ripard return 0; 79*c924ee25SMaxime Ripard } 80*c924ee25SMaxime Ripard 81*c924ee25SMaxime Ripard UCLASS_DRIVER(w1_eeprom) = { 82*c924ee25SMaxime Ripard .name = "w1_eeprom", 83*c924ee25SMaxime Ripard .id = UCLASS_W1_EEPROM, 84*c924ee25SMaxime Ripard .flags = DM_UC_FLAG_SEQ_ALIAS, 85*c924ee25SMaxime Ripard #if CONFIG_IS_ENABLED(OF_CONTROL) 86*c924ee25SMaxime Ripard .post_bind = dm_scan_fdt_dev, 87*c924ee25SMaxime Ripard #endif 88*c924ee25SMaxime Ripard }; 89*c924ee25SMaxime Ripard 90*c924ee25SMaxime Ripard int w1_eeprom_dm_init(void) 91*c924ee25SMaxime Ripard { 92*c924ee25SMaxime Ripard struct udevice *dev; 93*c924ee25SMaxime Ripard struct uclass *uc; 94*c924ee25SMaxime Ripard int ret; 95*c924ee25SMaxime Ripard 96*c924ee25SMaxime Ripard ret = uclass_get(UCLASS_W1_EEPROM, &uc); 97*c924ee25SMaxime Ripard if (ret) { 98*c924ee25SMaxime Ripard debug("W1_EEPROM uclass not available\n"); 99*c924ee25SMaxime Ripard return ret; 100*c924ee25SMaxime Ripard } 101*c924ee25SMaxime Ripard 102*c924ee25SMaxime Ripard uclass_foreach_dev(dev, uc) { 103*c924ee25SMaxime Ripard ret = device_probe(dev); 104*c924ee25SMaxime Ripard if (ret == -ENODEV) { /* No such device. */ 105*c924ee25SMaxime Ripard debug("W1_EEPROM not available.\n"); 106*c924ee25SMaxime Ripard continue; 107*c924ee25SMaxime Ripard } 108*c924ee25SMaxime Ripard 109*c924ee25SMaxime Ripard if (ret) { /* Other error. */ 110*c924ee25SMaxime Ripard printf("W1_EEPROM probe failed, error %d\n", ret); 111*c924ee25SMaxime Ripard continue; 112*c924ee25SMaxime Ripard } 113*c924ee25SMaxime Ripard } 114*c924ee25SMaxime Ripard 115*c924ee25SMaxime Ripard return 0; 116*c924ee25SMaxime Ripard } 117