Skip to content

Commit a6e3829

Browse files
amiclauscarlescufi
authored andcommitted
drivers: ethernet: adin2111: add adin1110 support
Add support for ADIN1110 10BASE-T1L Ethernet MAC-PHY. The ADIN1110 is an ultra low power, single port, 10BASE-T1L transceiver design for industrial Ethernet applications and is com- pliant with the IEEE® 802.3cg-2019™ Ethernet standard for long reach, 10 Mbps single pair Ethernet (SPE). Featuring an integrated media access control (MAC) interface, the ADIN1110 enables direct connectivity with a variety of host controllers via a 4-wire serial peripheral interface (SPI). This SPI enables the use of lower power processors without an integrated MAC, which provides for the lowest overall system level power consumption. The SPI can be configured to use the Open Alliance SPI protocol or a generic SPI protocol. Documentation: https://www.analog.com/en/products/adin1110.html Signed-off-by: Antoniu Miclaus <[email protected]>
1 parent 636fd6a commit a6e3829

File tree

5 files changed

+77
-17
lines changed

5 files changed

+77
-17
lines changed

drivers/ethernet/Kconfig.adin2111

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
menuconfig ETH_ADIN2111
55
bool "ADIN2111 2-port 10BASE-T1L Controller"
66
default y
7-
depends on DT_HAS_ADI_ADIN2111_ENABLED
7+
depends on DT_HAS_ADI_ADIN2111_ENABLED || DT_HAS_ADI_ADIN1110_ENABLED
88
select SPI
99
select MDIO
1010
help

drivers/ethernet/eth_adin2111.c

Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@
77
#include <zephyr/logging/log.h>
88
LOG_MODULE_REGISTER(eth_adin2111, CONFIG_ETHERNET_LOG_LEVEL);
99

10-
#define DT_DRV_COMPAT adi_adin2111
11-
1210
#include <zephyr/net/net_pkt.h>
1311
#include <zephyr/net/ethernet.h>
1412
#include <zephyr/net/phy.h>
@@ -269,6 +267,9 @@ static inline void adin2111_port_on_phyint(const struct device *dev)
269267
static void adin2111_offload_thread(const struct device *dev)
270268
{
271269
struct adin2111_data *ctx = dev->data;
270+
const struct adin2111_port_config *pcfg = dev->config;
271+
const struct adin2111_config *adin_cfg = pcfg->adin->config;
272+
bool is_adin2111 = (adin_cfg->id == ADIN2111_MAC);
272273
uint32_t status0;
273274
uint32_t status1;
274275
int ret;
@@ -312,7 +313,7 @@ static void adin2111_offload_thread(const struct device *dev)
312313
}
313314

314315
/* handle port 2 phy interrupts */
315-
if (status1 & ADIN2111_STATUS1_PHYINT) {
316+
if ((status1 & ADIN2111_STATUS1_PHYINT) && is_adin2111) {
316317
adin2111_port_on_phyint(ctx->port[1]);
317318
}
318319

@@ -332,7 +333,7 @@ static void adin2111_offload_thread(const struct device *dev)
332333
}
333334

334335
/* handle port 2 rx */
335-
if (status1 & ADIN2111_STATUS1_P2_RX_RDY) {
336+
if ((status1 & ADIN2111_STATUS1_P2_RX_RDY) && is_adin2111) {
336337
do {
337338
ret = adin2111_read_fifo(dev, 1U);
338339
if (ret < 0) {
@@ -570,9 +571,11 @@ static int adin2111_write_filter_address(const struct device *dev,
570571

571572
static int adin2111_filter_multicast(const struct device *dev)
572573
{
574+
const struct adin2111_config *cfg = dev->config;
575+
bool is_adin2111 = (cfg->id == ADIN2111_MAC);
573576
uint8_t mm[6] = {BIT(0), 0U, 0U, 0U, 0U, 0U};
574577
uint32_t rules = ADIN2111_ADDR_APPLY2PORT1 |
575-
ADIN2111_ADDR_APPLY2PORT2 |
578+
(is_adin2111 ? ADIN2111_ADDR_APPLY2PORT2 : 0) |
576579
ADIN2111_ADDR_TO_HOST |
577580
ADIN2111_ADDR_TO_OTHER_PORT;
578581

@@ -582,9 +585,11 @@ static int adin2111_filter_multicast(const struct device *dev)
582585

583586
static int adin2111_filter_broadcast(const struct device *dev)
584587
{
588+
const struct adin2111_config *cfg = dev->config;
589+
bool is_adin2111 = (cfg->id == ADIN2111_MAC);
585590
uint8_t mac[] = {0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU};
586591
uint32_t rules = ADIN2111_ADDR_APPLY2PORT1 |
587-
ADIN2111_ADDR_APPLY2PORT2 |
592+
(is_adin2111 ? ADIN2111_ADDR_APPLY2PORT2 : 0) |
588593
ADIN2111_ADDR_TO_HOST |
589594
ADIN2111_ADDR_TO_OTHER_PORT;
590595

@@ -727,7 +732,7 @@ static int adin2111_check_spi(const struct device *dev)
727732
for (count = 0U; count < ADIN2111_DEV_AWAIT_RETRY_COUNT; ++count) {
728733
ret = eth_adin2111_reg_read(dev, ADIN2111_PHYID, &val);
729734
if (ret >= 0) {
730-
if (val == ADIN2111_PHYID_RST_VAL) {
735+
if (val == ADIN2111_PHYID_RST_VAL || val == ADIN1110_PHYID_RST_VAL) {
731736
break;
732737
}
733738
ret = -ETIMEDOUT;
@@ -768,6 +773,7 @@ static int adin2111_await_device(const struct device *dev)
768773
static int adin2111_init(const struct device *dev)
769774
{
770775
const struct adin2111_config *cfg = dev->config;
776+
bool is_adin2111 = (cfg->id == ADIN2111_MAC);
771777
struct adin2111_data *ctx = dev->data;
772778
int ret;
773779
uint32_t val;
@@ -880,8 +886,8 @@ static int adin2111_init(const struct device *dev)
880886
/* The setting will take effect after the ports */
881887
/* are out of software powerdown. */
882888
val |= (ADIN2111_CONFIG2_PORT_CUT_THRU_EN |
883-
ADIN2111_CONFIG2_P1_FWD_UNK2P2 |
884-
ADIN2111_CONFIG2_P2_FWD_UNK2P1);
889+
(is_adin2111 ? ADIN2111_CONFIG2_P1_FWD_UNK2P2 : 0) |
890+
(is_adin2111 ? ADIN2111_CONFIG2_P2_FWD_UNK2P1 : 0));
885891

886892
ret = eth_adin2111_reg_write(dev, ADIN2111_CONFIG2, val);
887893
if (ret < 0) {
@@ -894,8 +900,8 @@ static int adin2111_init(const struct device *dev)
894900
ctx->imask1 = ~(ADIN2111_IMASK1_TX_RDY_MASK |
895901
ADIN2111_IMASK1_P1_RX_RDY_MASK |
896902
ADIN2111_IMASK1_SPI_ERR_MASK |
897-
ADIN2111_IMASK1_P2_RX_RDY_MASK |
898-
ADIN2111_IMASK1_P2_PHYINT_MASK);
903+
(is_adin2111 ? ADIN2111_IMASK1_P2_RX_RDY_MASK : 0) |
904+
(is_adin2111 ? ADIN2111_IMASK1_P2_PHYINT_MASK : 0));
899905

900906
/* enable interrupts */
901907
ret = eth_adin2111_reg_write(dev, ADIN2111_IMASK0, ctx->imask0);
@@ -956,15 +962,16 @@ static const struct ethernet_api adin2111_port_api = {
956962

957963
#define ADIN2111_SPI_OPERATION ((uint16_t)(SPI_OP_MODE_MASTER | SPI_TRANSFER_MSB | SPI_WORD_SET(8)))
958964

959-
#define ADIN2111_MAC_INITIALIZE(inst) \
965+
#define ADIN2111_MAC_INITIALIZE(inst, dev_id, ifaces) \
960966
static uint8_t __aligned(4) adin2111_buffer_##inst[CONFIG_ETH_ADIN2111_BUFFER_SIZE]; \
961967
static const struct adin2111_config adin2111_config_##inst = { \
968+
.id = dev_id, \
962969
.spi = SPI_DT_SPEC_INST_GET(inst, ADIN2111_SPI_OPERATION, 1), \
963970
.interrupt = GPIO_DT_SPEC_INST_GET(inst, int_gpios), \
964971
.reset = GPIO_DT_SPEC_INST_GET_OR(inst, reset_gpios, { 0 }), \
965972
}; \
966973
static struct adin2111_data adin2111_data_##inst = { \
967-
.ifaces_left_to_init = 2U, \
974+
.ifaces_left_to_init = ifaces, \
968975
.port = {}, \
969976
.offload_sem = Z_SEM_INITIALIZER(adin2111_data_##inst.offload_sem, 0, 1), \
970977
.lock = Z_MUTEX_INITIALIZER(adin2111_data_##inst.lock), \
@@ -974,9 +981,21 @@ static const struct ethernet_api adin2111_port_api = {
974981
DEVICE_DT_DEFINE(DT_DRV_INST(inst), adin2111_init, NULL, \
975982
&adin2111_data_##inst, &adin2111_config_##inst, \
976983
POST_KERNEL, CONFIG_ETH_ADIN2111_INIT_PRIORITY, \
977-
NULL); \
984+
NULL);
985+
986+
#define ADIN2111_MAC_INIT(inst) ADIN2111_MAC_INITIALIZE(inst, ADIN2111_MAC, 2) \
978987
/* ports */ \
979988
ADIN2111_PORT_DEVICE_INIT_INSTANCE(inst, 0, 1) \
980989
ADIN2111_PORT_DEVICE_INIT_INSTANCE(inst, 1, 2)
981990

982-
DT_INST_FOREACH_STATUS_OKAY(ADIN2111_MAC_INITIALIZE)
991+
#undef DT_DRV_COMPAT
992+
#define DT_DRV_COMPAT adi_adin2111
993+
DT_INST_FOREACH_STATUS_OKAY(ADIN2111_MAC_INIT)
994+
995+
#define ADIN1110_MAC_INIT(inst) ADIN2111_MAC_INITIALIZE(inst, ADIN1110_MAC, 1) \
996+
/* ports */ \
997+
ADIN2111_PORT_DEVICE_INIT_INSTANCE(inst, 0, 1)
998+
999+
#undef DT_DRV_COMPAT
1000+
#define DT_DRV_COMPAT adi_adin1110
1001+
DT_INST_FOREACH_STATUS_OKAY(ADIN1110_MAC_INIT)

drivers/ethernet/eth_adin2111_priv.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#define ADIN2111_PHYID 0x01U
2121
/* PHY Identification Register Reset Value */
2222
#define ADIN2111_PHYID_RST_VAL 0x0283BCA1U
23+
#define ADIN1110_PHYID_RST_VAL 0x0283BC91U
2324

2425
/* Reset Control and Status Register */
2526
#define ADIN2111_RESET 0x03U
@@ -157,7 +158,13 @@
157158
/* Number of buffer bytes in TxFIFO to provide frame margin upon writes */
158159
#define ADIN2111_TX_FIFO_BUFFER_MARGIN 4U
159160

161+
enum adin2111_chips_id {
162+
ADIN2111_MAC = 0,
163+
ADIN1110_MAC,
164+
};
165+
160166
struct adin2111_config {
167+
enum adin2111_chips_id id;
161168
struct spi_dt_spec spi;
162169
struct gpio_dt_spec interrupt;
163170
struct gpio_dt_spec reset;

drivers/ethernet/phy/phy_adin2111.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ LOG_MODULE_REGISTER(phy_adin2111, CONFIG_PHY_LOG_LEVEL);
3535

3636
/* ADIN2111 PHY identifier */
3737
#define ADIN2111_PHY_ID 0x0283BCA1U
38+
#define ADIN1110_PHY_ID 0x0283BC91U
3839

3940
/* 10BASE-T1L PMA Status Register */
4041
#define ADIN2111_PHY_PMA_STATUS 0x000108F7U
@@ -353,7 +354,7 @@ static int phy_adin2111_init(const struct device *dev)
353354
return -ENODEV;
354355
}
355356

356-
if (phy_id != ADIN2111_PHY_ID) {
357+
if (phy_id != ADIN2111_PHY_ID && phy_id != ADIN1110_PHY_ID) {
357358
LOG_ERR("PHY %u unexpected PHY ID %X", cfg->phy_addr, phy_id);
358359
return -EINVAL;
359360
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Copyright (c) 2023 Analog Devices Inc.
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
description: |
5+
ADIN1110 standalone 10BASE-T1L Ethernet controller with SPI interface.
6+
7+
An example:
8+
9+
adin1110: adin1110@0 {
10+
compatible = "adi,adin1110";
11+
reg = <0x0>;
12+
spi-max-frequency = <25000000>;
13+
int-gpios = <&gpioe 12 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
14+
reset-gpios = <&gpioe 8 GPIO_ACTIVE_LOW>;
15+
port1 {
16+
local-mac-address = [ CA 2F B7 10 23 63 ];
17+
};
18+
mdio: mdio {
19+
compatible = "adi,adin2111-mdio";
20+
status = "okay";
21+
#address-cells = <1>;
22+
#size-cells = <0>;
23+
phy@1 {
24+
reg = <0x1>;
25+
compatible = "adi,adin2111-phy";
26+
status = "okay";
27+
};
28+
};
29+
};
30+
31+
compatible: "adi,adin1110"
32+
33+
include: adi,adin2111.yaml

0 commit comments

Comments
 (0)