1010#include  <zephyr/drivers/pinctrl.h> 
1111#include  <zephyr/kernel.h> 
1212#include  <zephyr/logging/log.h> 
13- #if  defined(CONFIG_I2C_SILABS_DMA )
1413#include  <zephyr/drivers/dma.h> 
15- #endif 
1614#include  <zephyr/drivers/clock_control.h> 
1715#include  <zephyr/drivers/clock_control/clock_control_silabs.h> 
1816#include  <zephyr/pm/device.h> 
1917#include  <zephyr/pm/device_runtime.h> 
2018#include  <zephyr/pm/policy.h> 
21- #include  <sl_hal_i2c.h> 
2219#include  <sl_i2c.h> 
23- #include  <sl_status.h> 
2420#include  <sli_i2c.h> 
2521
2622#define  LOG_LEVEL  CONFIG_I2C_LOG_LEVEL
@@ -36,7 +32,7 @@ struct i2c_silabs_dma_config {
3632/* Structure for I2C device configuration */ 
3733struct  i2c_silabs_dev_config  {
3834	const  struct  pinctrl_dev_config  * pcfg ; /* Pin configuration for the I2C instance */ 
39- 	I2C_TypeDef   * base ;                      /* I2C peripheral base address  */ 
35+ 	sl_peripheral_t   peripheral ;            /* I2C peripheral structure  */ 
4036	uint32_t  bitrate ;                      /* I2C bitrate (clock frequency) */ 
4137	void  (* irq_config_func )(void );         /* IRQ configuration function */ 
4238	const  struct  device  * clock ;            /* Clock device */ 
@@ -47,11 +43,12 @@ struct i2c_silabs_dev_config {
4743struct  i2c_silabs_dev_data  {
4844	struct  k_sem  bus_lock ;               /* Semaphore to lock the I2C bus */ 
4945	struct  k_sem  transfer_sem ;           /* Semaphore to manage transfer */ 
50- 	sli_i2c_instance_t   i2c_instance ;     /* I2C instance  structure */ 
46+ 	sl_i2c_handle_t   i2c_handle ;           /* I2C handle  structure */ 
5147	struct  i2c_silabs_dma_config  dma_rx ; /* DMA configuration for RX */ 
5248	struct  i2c_silabs_dma_config  dma_tx ; /* DMA configuration for TX */ 
5349	bool  asynchronous ;                   /* Indicates if transfer is asynchronous */ 
5450	bool  last_transfer ;                  /* Transfer is the last in the sequence */ 
51+ 	bool  is_10bit_addr ;                  /* Indicates if addr is 7-bit or 10-bit */ 
5552#if  defined CONFIG_I2C_CALLBACK 
5653	i2c_callback_t  callback ; /* I2C callback function pointer */ 
5754	void  * callback_context ;  /* Context for I2C callback */ 
@@ -64,15 +61,11 @@ static int i2c_silabs_pm_action(const struct device *dev, enum pm_device_action
6461
6562static  bool  i2c_silabs_is_dma_enabled_instance (const  struct  device  * dev )
6663{
67- #ifdef  CONFIG_I2C_SILABS_DMA 
6864	struct  i2c_silabs_dev_data  * data  =  dev -> data ;
6965
7066	__ASSERT_NO_MSG (!!data -> dma_tx .dma_dev  ==  !!data -> dma_rx .dma_dev );
7167
7268	return  data -> dma_rx .dma_dev  !=  NULL ;
73- #else 
74- 	return  false;
75- #endif 
7669}
7770
7871static  void  i2c_silabs_pm_policy_state_lock_get (const  struct  device  * dev )
@@ -92,18 +85,17 @@ static int i2c_silabs_dev_configure(const struct device *dev, uint32_t dev_confi
9285{
9386	const  struct  i2c_silabs_dev_config  * config  =  dev -> config ;
9487	struct  i2c_silabs_dev_data  * data  =  dev -> data ;
95- 	sl_i2c_init_params_t  init_params ;
9688
9789	/* Determine the I2C speed and corresponding baudrate */ 
9890	switch  (I2C_SPEED_GET (dev_config )) {
9991	case  I2C_SPEED_STANDARD :
100- 		init_params . freq_mode  =  SL_I2C_FREQ_STANDARD_MODE ;
92+ 		data -> i2c_handle . frequency_mode  =  SL_I2C_FREQ_STANDARD_MODE ;
10193		break ;
10294	case  I2C_SPEED_FAST :
103- 		init_params . freq_mode  =  SL_I2C_FREQ_FAST_MODE ;
95+ 		data -> i2c_handle . frequency_mode  =  SL_I2C_FREQ_FAST_MODE ;
10496		break ;
10597	case  I2C_SPEED_FAST_PLUS :
106- 		init_params . freq_mode  =  SL_I2C_FREQ_FASTPLUS_MODE ;
98+ 		data -> i2c_handle . frequency_mode  =  SL_I2C_FREQ_FASTPLUS_MODE ;
10799		break ;
108100	default :
109101		return  - EINVAL ;
@@ -112,19 +104,13 @@ static int i2c_silabs_dev_configure(const struct device *dev, uint32_t dev_confi
112104	/* Take the bus lock semaphore to ensure exclusive access */ 
113105	k_sem_take (& data -> bus_lock , K_FOREVER );
114106	/* Initialize I2C parameters */ 
115- 	init_params .i2c_base_addr  =  config -> base ;
116- 	data -> i2c_instance .i2c_base_addr  =  init_params .i2c_base_addr ;
107+ 	data -> i2c_handle .i2c_peripheral  =  config -> peripheral ;
117108
118- 	/* Set the operating mode (leader or follower) */ 
119- #if  defined(CONFIG_I2C_TARGET )
120- 	init_params .operating_mode  =  SL_I2C_FOLLOWER_MODE ;
121- #else 
122- 	init_params .operating_mode  =  SL_I2C_LEADER_MODE ;
123- #endif  /* CONFIG_I2C_TARGET */ 
124- 	data -> i2c_instance .operating_mode  =  init_params .operating_mode ;
109+ 	/* Set the operating mode (leader) */ 
110+ 	data -> i2c_handle .operating_mode  =  SL_I2C_LEADER_MODE ;
125111
126112	/* Configure the I2C instance */ 
127- 	sli_i2c_instance_configuration ( & init_params );
113+ 	sli_i2c_init_core ( & data -> i2c_handle );
128114
129115	/* Release the bus lock semaphore */ 
130116	k_sem_give (& data -> bus_lock );
@@ -137,25 +123,21 @@ static int i2c_silabs_transfer_dma(const struct device *dev, struct i2c_msg *msg
137123				   uint16_t  addr , i2c_callback_t  cb , void  * userdata ,
138124				   bool  asynchronous )
139125{
140- #if  defined(CONFIG_I2C_SILABS_DMA )
141126	struct  i2c_silabs_dev_data  * data  =  dev -> data ;
142- 	__maybe_unused  const  struct  i2c_silabs_dev_config  * config  =  dev -> config ;
143- 	sl_i2c_handle_t  * i2c_handle  =  (sl_i2c_handle_t  * )& data -> i2c_instance ;
144127#if  defined(CONFIG_I2C_CALLBACK )
145128	data -> callback_invoked  =  false;
146129#endif 
147130	data -> pm_lock_done  =  false;
148131	uint8_t  i  =  0 ;
149132	int  err  =  0 ;
150133
134+ 	if  (!IS_ENABLED (CONFIG_I2C_SILABS_DMA )) {
135+ 		return  - ENOTSUP ;
136+ 	}
137+ 
151138	/* Get the power management policy state lock */ 
152139	i2c_silabs_pm_policy_state_lock_get (dev );
153140
154- #if  defined(CONFIG_I2C_TARGET )
155- 	/* Set follower address in target mode */ 
156- 	sli_i2c_set_follower_address (config -> base , addr , data -> i2c_instance .is_10bit_addr );
157- #endif  /* CONFIG_I2C_TARGET */ 
158- 
159141	while  (i  <  num_msgs ) {
160142		uint8_t  msgs_in_transfer  =  1 ;
161143
@@ -167,24 +149,27 @@ static int i2c_silabs_transfer_dma(const struct device *dev, struct i2c_msg *msg
167149		data -> last_transfer  =  (i  +  msgs_in_transfer ) ==  num_msgs ;
168150
169151		if  (msgs_in_transfer  ==  2 ) {
170- 			if  (sl_i2c_transfer_non_blocking ( i2c_handle ,  msgs [ i ]. buf ,  msgs [ i ]. len , 
171- 							  msgs [i   +   1 ].buf , msgs [i   +   1 ].len ,  NULL ,
172- 							  NULL ) !=  0 ) {
152+ 			if  (sl_i2c_leader_transfer_non_blocking ( 
153+ 				     & data -> i2c_handle ,  addr ,  msgs [i ].buf , msgs [i ].len ,
154+ 				     msgs [ i   +   1 ]. buf ,  msgs [ i   +   1 ]. len ,  NULL ) !=  0 ) {
173155				k_sem_give (& data -> bus_lock );
156+ 				i2c_silabs_pm_policy_state_lock_put (dev );
174157				return  - EIO ;
175158			}
176159		} else  if  (msgs [i ].flags  &  I2C_MSG_READ ) {
177160			/* Start DMA receive */ 
178- 			if  (sl_i2c_receive_non_blocking ( i2c_handle , msgs [ i ]. buf , msgs [i ].len ,  NULL ,
179- 							NULL ) !=  0 ) {
161+ 			if  (sl_i2c_leader_receive_non_blocking ( & data -> i2c_handle , addr , msgs [i ].buf ,
162+ 							        msgs [ i ]. len ,  NULL ) !=  0 ) {
180163				k_sem_give (& data -> bus_lock );
164+ 				i2c_silabs_pm_policy_state_lock_put (dev );
181165				return  - EIO ;
182166			}
183167		} else  {
184168			/* Start DMA send */ 
185- 			if  (sl_i2c_send_non_blocking ( i2c_handle , msgs [ i ]. buf , msgs [i ].len ,  NULL ,
186- 						     NULL ) !=  0 ) {
169+ 			if  (sl_i2c_leader_send_non_blocking ( & data -> i2c_handle , addr , msgs [i ].buf ,
170+ 							     msgs [ i ]. len ,  NULL ) !=  0 ) {
187171				k_sem_give (& data -> bus_lock );
172+ 				i2c_silabs_pm_policy_state_lock_put (dev );
188173				return  - EIO ;
189174			}
190175		}
@@ -193,30 +178,28 @@ static int i2c_silabs_transfer_dma(const struct device *dev, struct i2c_msg *msg
193178			if  (k_sem_take (& data -> transfer_sem , K_MSEC (CONFIG_I2C_SILABS_TIMEOUT ))) {
194179				err  =  - ETIMEDOUT ;
195180			}
196- 			if  (data -> i2c_instance .state  ==  SLI_I2C_STATE_ERROR ) {
181+ 			if  (data -> i2c_handle .state  ==  SL_I2C_STATE_ERROR ) {
197182				err  =  - EIO ;
198183			}
199184			k_sem_reset (& data -> transfer_sem );
200185			if  (err  <  0 ) {
186+ 				i2c_silabs_pm_policy_state_lock_put (dev );
201187				break ;
202188			}
203189		}
204190		i  +=  msgs_in_transfer ;
205191	}
206192
207193	return  err ;
208- #else 
209- 	return  - ENOTSUP ;
210- #endif  /* CONFIG_I2C_SILABS_DMA */ 
211194}
212195
213196/* Function to handle synchronous transfer */ 
214197static  int  i2c_silabs_transfer_sync (const  struct  device  * dev , struct  i2c_msg  * msgs ,
215198				    uint8_t  num_msgs , uint16_t  addr )
216199{
217200	struct  i2c_silabs_dev_data  * data  =  dev -> data ;
218- 	sl_i2c_handle_t  * i2c_handle  =  (sl_i2c_handle_t  * )& data -> i2c_instance ;
219201	uint8_t  i  =  0 ;
202+ 	int  err  =  0 ;
220203
221204	/* Get the power management policy state lock */ 
222205	i2c_silabs_pm_policy_state_lock_get (dev );
@@ -227,35 +210,43 @@ static int i2c_silabs_transfer_sync(const struct device *dev, struct i2c_msg *ms
227210		if  ((msgs [i ].flags  &  I2C_MSG_WRITE ) ==  0  &&  (i  +  1  <  num_msgs ) && 
228211		    (msgs [i  +  1 ].flags  &  I2C_MSG_READ )) {
229212			msgs_in_transfer  =  2 ;
230- 			if  (sl_i2c_transfer (i2c_handle , msgs [i ].buf , msgs [i ].len , msgs [i  +  1 ].buf ,
231- 					    msgs [i  +  1 ].len ) !=  0 ) {
213+ 			if  (sl_i2c_leader_transfer_blocking (& data -> i2c_handle , addr , msgs [i ].buf ,
214+ 							    msgs [i ].len , msgs [i  +  1 ].buf ,
215+ 							    msgs [i  +  1 ].len ,
216+ 							    CONFIG_I2C_SILABS_TIMEOUT ) !=  0 ) {
232217				k_sem_give (& data -> bus_lock );
233- 				return  - EIO ;
218+ 				err  =  - EIO ;
219+ 				goto out ;
234220			}
235221			i ++ ;
236222		} else  if  (msgs [i ].flags  &  I2C_MSG_READ ) {
237- 			if  (sl_i2c_receive_blocking (i2c_handle , msgs [i ].buf , msgs [i ].len ,
238- 						    CONFIG_I2C_SILABS_TIMEOUT ) !=  0 ) {
223+ 			if  (sl_i2c_leader_receive_blocking (& data -> i2c_handle , addr , msgs [i ].buf ,
224+ 							   msgs [i ].len ,
225+ 							   CONFIG_I2C_SILABS_TIMEOUT ) !=  0 ) {
239226				k_sem_give (& data -> bus_lock );
240- 				return  - ETIMEDOUT ;
227+ 				err  =  - ETIMEDOUT ;
228+ 				goto out ;
241229			}
242230		} else  {
243- 			if  (sl_i2c_send_blocking (i2c_handle , msgs [i ].buf , msgs [i ].len ,
244- 						 CONFIG_I2C_SILABS_TIMEOUT ) !=  0 ) {
231+ 			if  (sl_i2c_leader_send_blocking (& data -> i2c_handle , addr , msgs [i ].buf ,
232+ 							msgs [i ].len ,
233+ 							CONFIG_I2C_SILABS_TIMEOUT ) !=  0 ) {
245234				k_sem_give (& data -> bus_lock );
246- 				return  - ETIMEDOUT ;
235+ 				err  =  - ETIMEDOUT ;
236+ 				goto out ;
247237			}
248238		}
249239		i  +=  msgs_in_transfer ;
250240	}
251241
242+ out :
252243	/* Release the bus lock semaphore */ 
253244	k_sem_give (& data -> bus_lock );
254245
255246	/* Release the power management policy state lock */ 
256247	i2c_silabs_pm_policy_state_lock_put (dev );
257248
258- 	return  0 ;
249+ 	return  err ;
259250}
260251
261252/* Function to perform I2C transfer */ 
@@ -264,8 +255,6 @@ static int i2c_silabs_transfer_impl(const struct device *dev, struct i2c_msg *ms
264255				    void  * userdata )
265256{
266257	struct  i2c_silabs_dev_data  * data  =  dev -> data ;
267- 	__maybe_unused  const  struct  i2c_silabs_dev_config  * config  =  dev -> config ;
268- 	sl_i2c_handle_t  * i2c_handle  =  (sl_i2c_handle_t  * )& data -> i2c_instance ;
269258	int  ret  =  - EINVAL ; /* Initialize ret to a default error value */ 
270259
271260	/* Check for invalid number of messages */ 
@@ -276,9 +265,9 @@ static int i2c_silabs_transfer_impl(const struct device *dev, struct i2c_msg *ms
276265	/* Check and set the address mode (7-bit or 10-bit) based on */ 
277266	/* the provided address */ 
278267	if  (addr  <= 0x7F ) {
279- 		data -> i2c_instance . is_10bit_addr  =  false; /* 7-bit address */ 
268+ 		data -> is_10bit_addr  =  false; /* 7-bit address */ 
280269	} else  if  (addr  <= 0x3FF ) {
281- 		data -> i2c_instance . is_10bit_addr  =  true; /* 10-bit address */ 
270+ 		data -> is_10bit_addr  =  true; /* 10-bit address */ 
282271	} else  {
283272		return  - EINVAL ;
284273	}
@@ -292,12 +281,6 @@ static int i2c_silabs_transfer_impl(const struct device *dev, struct i2c_msg *ms
292281		return  ret ;
293282	}
294283
295- 	/* Set the follower address */ 
296- 	if  (sl_i2c_set_follower_address (i2c_handle , addr ) !=  0 ) {
297- 		k_sem_give (& data -> bus_lock );
298- 		return  - EINVAL ;
299- 	}
300- 
301284	if  (i2c_silabs_is_dma_enabled_instance (dev )) {
302285		/* DMA transfer handle a/synchronous transfers */ 
303286		ret  =  i2c_silabs_transfer_dma (dev , msgs , num_msgs , addr , cb , userdata ,
@@ -373,25 +356,23 @@ static int i2c_silabs_dev_init(const struct device *dev)
373356		return  - EINVAL ;
374357	}
375358
376- #if  defined(CONFIG_I2C_SILABS_DMA )
377359	if  (i2c_silabs_is_dma_enabled_instance (dev )) {
378360		if  (!device_is_ready (data -> dma_rx .dma_dev ) || 
379361		    !device_is_ready (data -> dma_tx .dma_dev )) {
380362			return  - ENODEV ;
381363		}
382364		data -> dma_rx .dma_channel  =  dma_request_channel (data -> dma_rx .dma_dev , NULL );
383- 		data -> i2c_instance .dma_channel .dma_rx_channel  =  data -> dma_rx .dma_channel ;
365+ 		data -> i2c_handle .dma_channel .dma_rx_channel  =  data -> dma_rx .dma_channel ;
384366
385367		data -> dma_tx .dma_channel  =  dma_request_channel (data -> dma_tx .dma_dev , NULL );
386- 		data -> i2c_instance .dma_channel .dma_tx_channel  =  data -> dma_tx .dma_channel ;
368+ 		data -> i2c_handle .dma_channel .dma_tx_channel  =  data -> dma_tx .dma_channel ;
387369
388370		if  (data -> dma_rx .dma_channel  <  0  ||  data -> dma_tx .dma_channel  <  0 ) {
389371			dma_release_channel (data -> dma_rx .dma_dev , data -> dma_rx .dma_channel );
390372			dma_release_channel (data -> dma_tx .dma_dev , data -> dma_tx .dma_channel );
391373			return  - EAGAIN ;
392374		}
393375	}
394- #endif  /* CONFIG_I2C_SILABS_DMA */ 
395376
396377	/* Configure IRQ */ 
397378	config -> irq_config_func ();
@@ -445,15 +426,10 @@ static int i2c_silabs_pm_action(const struct device *dev, enum pm_device_action
445426void  i2c_silabs_isr_handler (const  struct  device  * dev )
446427{
447428	struct  i2c_silabs_dev_data  * data  =  dev -> data ;
448- 	sli_i2c_instance_t   * sl_i2c_instance  =  & data -> i2c_instance ;
429+ 	sl_i2c_handle_t   * sl_i2c_handle  =  & data -> i2c_handle ;
449430
450- #if  defined(CONFIG_I2C_TARGET )
451- 	sli_i2c_follower_dispatch_interrupt (sl_i2c_instance );
452- #else 
453- 	sli_i2c_leader_dispatch_interrupt (sl_i2c_instance );
454- #endif 
455- 	if  (sl_i2c_instance -> transfer_event  !=  SL_I2C_EVENT_IN_PROGRESS  && 
456- 	    sl_i2c_instance -> rstart  ==  0 ) {
431+ 	sli_i2c_leader_dispatch_interrupt (sl_i2c_handle );
432+ 	if  (sl_i2c_handle -> event  !=  SL_I2C_EVENT_IN_PROGRESS ) {
457433		if  (!data -> asynchronous ) {
458434			k_sem_give (& data -> transfer_sem );
459435		}
@@ -462,9 +438,9 @@ void i2c_silabs_isr_handler(const struct device *dev)
462438			int  err  =  0 ;
463439
464440			data -> callback_invoked  =  true;
465- 			if  (sl_i2c_instance -> transfer_event  ==  SL_I2C_EVENT_ARBITRATION_LOST  || 
466- 			    sl_i2c_instance -> transfer_event  ==  SL_I2C_EVENT_BUS_ERROR  || 
467- 			    sl_i2c_instance -> transfer_event  ==  SL_I2C_EVENT_INVALID_ADDR ) {
441+ 			if  (sl_i2c_handle -> event  ==  SL_I2C_EVENT_ARBITRATION_LOST  || 
442+ 			    sl_i2c_handle -> event  ==  SL_I2C_EVENT_BUS_ERROR  || 
443+ 			    sl_i2c_handle -> event  ==  SL_I2C_EVENT_INVALID_ADDR ) {
468444				err  =  - EIO ;
469445			}
470446			data -> callback (dev , err , data -> callback_context );
@@ -503,10 +479,17 @@ static DEVICE_API(i2c, i2c_silabs_dev_driver_api) = {
503479			     irq_enable(DT_INST_IRQ(idx, irq));),                                  \
504480			    ())									   \
505481	}                                                                                          \
506-                                                                                                    \
482+ 	                                                                                           \
483+ 	static const uint32_t i2c_bus_clock_##idx = DT_INST_CLOCKS_CELL(idx, enable);              \
484+ 	static const sl_peripheral_val_t i2c_peripheral_val_##idx = {                              \
485+ 		.base = DT_INST_REG_ADDR(idx),                                                     \
486+ 		.clk_branch = DT_INST_CLOCKS_CELL(idx, branch),                                    \
487+ 		.bus_clock = (DT_INST_CLOCKS_CELL(idx, enable) ? &i2c_bus_clock_##idx : NULL),     \
488+ 	};                                                                                         \
489+ 												   \
507490	static const struct i2c_silabs_dev_config i2c_silabs_dev_config_##idx = {                  \
508491		.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(idx),                                       \
509- 		.base  = (I2C_TypeDef *)DT_INST_REG_ADDR( idx),                                       \
492+ 		.peripheral  = &i2c_peripheral_val_## idx,                                            \
510493		.bitrate = DT_INST_PROP(idx, clock_frequency),                                     \
511494		.irq_config_func = i2c_silabs_irq_config_##idx,                                    \
512495		.clock = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(idx)),                                  \
0 commit comments