blob: 270af2506d21a777065ec48742883871445eb50e [file] [log] [blame]
Kory Maincentfe4c1552021-05-04 19:31:27 +02001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * (C) Copyright 2021
4 * Köry Maincent, Bootlin, <kory.maincent@bootlin.com>
5 * Based on initial code from Maxime Ripard
6 */
7
Kory Maincentfe4c1552021-05-04 19:31:27 +02008#include <malloc.h>
9#include <dm.h>
10#include <w1.h>
11#include <w1-eeprom.h>
12#include <dm/device-internal.h>
13
Andre Przywaraf944a612022-09-06 10:36:38 +010014#include <sunxi_gpio.h>
Kory Maincentfe4c1552021-05-04 19:31:27 +020015
16#include <extension_board.h>
17
18#define for_each_w1_device(b, d) \
19 for (device_find_first_child(b, d); *d; device_find_next_child(d))
20
21#define dip_convert(field) \
22 ( \
23 (sizeof(field) == 1) ? field : \
24 (sizeof(field) == 2) ? be16_to_cpu(field) : \
25 (sizeof(field) == 4) ? be32_to_cpu(field) : \
26 -1 \
27 )
28
29#define DIP_MAGIC 0x50494843 /* CHIP */
30
31struct dip_w1_header {
32 u32 magic; /* CHIP */
33 u8 version; /* spec version */
34 u32 vendor_id;
35 u16 product_id;
36 u8 product_version;
37 char vendor_name[32];
38 char product_name[32];
39 u8 rsvd[36]; /* rsvd for future spec versions */
40 u8 data[16]; /* user data, per-dip specific */
41} __packed;
42
43int extension_board_scan(struct list_head *extension_list)
44{
45 struct extension *dip;
46 struct dip_w1_header w1_header;
47 struct udevice *bus, *dev;
48 u32 vid;
49 u16 pid;
50 int ret;
51
52 int num_dip = 0;
53
54 sunxi_gpio_set_pull(SUNXI_GPD(2), SUNXI_GPIO_PULL_UP);
55
56 ret = w1_get_bus(0, &bus);
57 if (ret) {
58 printf("one wire interface not found\n");
59 return 0;
60 }
61
62 for_each_w1_device(bus, &dev) {
63 if (w1_get_device_family(dev) != W1_FAMILY_DS2431)
64 continue;
65
66 ret = device_probe(dev);
67 if (ret) {
68 printf("Couldn't probe device %s: error %d",
69 dev->name, ret);
70 continue;
71 }
72
73 w1_eeprom_read_buf(dev, 0, (u8 *)&w1_header, sizeof(w1_header));
74
75 if (w1_header.magic != DIP_MAGIC)
76 continue;
77
78 vid = dip_convert(w1_header.vendor_id);
79 pid = dip_convert(w1_header.product_id);
80
81 printf("DIP: %s (0x%x) from %s (0x%x)\n",
82 w1_header.product_name, pid,
83 w1_header.vendor_name, vid);
84
85 dip = calloc(1, sizeof(struct extension));
86 if (!dip) {
87 printf("Error in memory allocation\n");
88 return num_dip;
89 }
90
91 snprintf(dip->overlay, sizeof(dip->overlay), "dip-%x-%x.dtbo",
92 vid, pid);
93 strncpy(dip->name, w1_header.product_name, 32);
94 strncpy(dip->owner, w1_header.vendor_name, 32);
95 list_add_tail(&dip->list, extension_list);
96 num_dip++;
97 }
98 return num_dip;
99}