1717#include <linux/string_choices.h>
1818#include <linux/swab.h>
1919#include <linux/types.h>
20+ #include <linux/unaligned.h>
2021#include <linux/workqueue.h>
2122
2223#include "cs35l56.h"
@@ -59,8 +60,6 @@ static int cs35l56_sdw_slow_read(struct sdw_slave *peripheral, unsigned int reg,
5960{
6061 int ret , i ;
6162
62- reg += CS35L56_SDW_ADDR_OFFSET ;
63-
6463 for (i = 0 ; i < val_size ; i += sizeof (u32 )) {
6564 /* Poll for bus bridge idle */
6665 ret = cs35l56_sdw_poll_mem_status (peripheral ,
@@ -97,57 +96,23 @@ static int cs35l56_sdw_slow_read(struct sdw_slave *peripheral, unsigned int reg,
9796 return 0 ;
9897}
9998
100- static int cs35l56_sdw_read_one (struct sdw_slave * peripheral , unsigned int reg , void * buf )
101- {
102- int ret ;
103-
104- ret = sdw_nread_no_pm (peripheral , reg , 4 , (u8 * )buf );
105- if (ret != 0 ) {
106- dev_err (& peripheral -> dev , "Read failed @%#x:%d\n" , reg , ret );
107- return ret ;
108- }
109-
110- swab32s ((u32 * )buf );
111-
112- return 0 ;
113- }
114-
11599static int cs35l56_sdw_read (void * context , const void * reg_buf ,
116100 const size_t reg_size , void * val_buf ,
117101 size_t val_size )
118102{
119103 struct sdw_slave * peripheral = context ;
120- u8 * buf8 = val_buf ;
121- unsigned int reg , bytes ;
104+ struct cs35l56_private * cs35l56 = dev_get_drvdata ( & peripheral -> dev ) ;
105+ unsigned int reg_addr = get_unaligned_le32 ( reg_buf ) ;
122106 int ret ;
123107
124- reg = le32_to_cpu (* (const __le32 * )reg_buf );
108+ if (cs35l56_is_otp_register (reg_addr - CS35L56_SDW_ADDR_OFFSET ))
109+ return cs35l56_sdw_slow_read (peripheral , reg_addr , (u8 * )val_buf , val_size );
125110
126- if (cs35l56_is_otp_register (reg ))
127- return cs35l56_sdw_slow_read (peripheral , reg , buf8 , val_size );
128-
129- reg += CS35L56_SDW_ADDR_OFFSET ;
130-
131- if (val_size == 4 )
132- return cs35l56_sdw_read_one (peripheral , reg , val_buf );
133-
134- while (val_size ) {
135- bytes = SDW_REG_NO_PAGE - (reg & SDW_REGADDR ); /* to end of page */
136- if (bytes > val_size )
137- bytes = val_size ;
138-
139- ret = sdw_nread_no_pm (peripheral , reg , bytes , buf8 );
140- if (ret != 0 ) {
141- dev_err (& peripheral -> dev , "Read failed @%#x..%#x:%d\n" ,
142- reg , reg + bytes - 1 , ret );
143- return ret ;
144- }
111+ ret = regmap_raw_read (cs35l56 -> sdw_bus_regmap , reg_addr , val_buf , val_size );
112+ if (ret )
113+ return ret ;
145114
146- swab32_array ((u32 * )buf8 , bytes / 4 );
147- val_size -= bytes ;
148- reg += bytes ;
149- buf8 += bytes ;
150- }
115+ swab32_array ((u32 * )val_buf , val_size / sizeof (u32 ));
151116
152117 return 0 ;
153118}
@@ -161,58 +126,34 @@ static inline void cs35l56_swab_copy(void *dest, const void *src, size_t nbytes)
161126 * dest32 ++ = swab32 (* src32 ++ );
162127}
163128
164- static int cs35l56_sdw_write_one (struct sdw_slave * peripheral , unsigned int reg , const void * buf )
165- {
166- u32 val_le = swab32 (* (u32 * )buf );
167- int ret ;
168-
169- ret = sdw_nwrite_no_pm (peripheral , reg , 4 , (u8 * )& val_le );
170- if (ret != 0 ) {
171- dev_err (& peripheral -> dev , "Write failed @%#x:%d\n" , reg , ret );
172- return ret ;
173- }
174-
175- return 0 ;
176- }
177-
178129static int cs35l56_sdw_gather_write (void * context ,
179130 const void * reg_buf , size_t reg_size ,
180131 const void * val_buf , size_t val_size )
181132{
182133 struct sdw_slave * peripheral = context ;
183- const u8 * src_be = val_buf ;
184- u32 val_le_buf [ 64 ]; /* Define u32 so it is 32-bit aligned */
185- unsigned int reg , bytes ;
134+ struct cs35l56_private * cs35l56 = dev_get_drvdata ( & peripheral -> dev ) ;
135+ unsigned int reg_addr = get_unaligned_le32 ( reg_buf );
136+ u32 swab_buf [ 64 ]; /* Define u32 so it is 32-bit aligned */
186137 int ret ;
187138
188- reg = le32_to_cpu (* (const __le32 * )reg_buf );
189- reg += CS35L56_SDW_ADDR_OFFSET ;
190-
191- if (val_size == 4 )
192- return cs35l56_sdw_write_one (peripheral , reg , src_be );
193-
194- while (val_size ) {
195- bytes = SDW_REG_NO_PAGE - (reg & SDW_REGADDR ); /* to end of page */
196- if (bytes > val_size )
197- bytes = val_size ;
198- if (bytes > sizeof (val_le_buf ))
199- bytes = sizeof (val_le_buf );
200-
201- cs35l56_swab_copy (val_le_buf , src_be , bytes );
202-
203- ret = sdw_nwrite_no_pm (peripheral , reg , bytes , (u8 * )val_le_buf );
204- if (ret != 0 ) {
205- dev_err (& peripheral -> dev , "Write failed @%#x..%#x:%d\n" ,
206- reg , reg + bytes - 1 , ret );
139+ while (val_size > sizeof (swab_buf )) {
140+ cs35l56_swab_copy (swab_buf , val_buf , sizeof (swab_buf ));
141+ ret = regmap_raw_write (cs35l56 -> sdw_bus_regmap , reg_addr ,
142+ swab_buf , sizeof (swab_buf ));
143+ if (ret )
207144 return ret ;
208- }
209145
210- val_size -= bytes ;
211- reg += bytes ;
212- src_be += bytes ;
146+ val_size -= sizeof ( swab_buf ) ;
147+ reg_addr += sizeof ( swab_buf ) ;
148+ val_buf += sizeof ( swab_buf ) ;
213149 }
214150
215- return 0 ;
151+ if (val_size == 0 )
152+ return 0 ;
153+
154+ cs35l56_swab_copy (swab_buf , val_buf , val_size );
155+
156+ return regmap_raw_write (cs35l56 -> sdw_bus_regmap , reg_addr , swab_buf , val_size );
216157}
217158
218159static int cs35l56_sdw_write (void * context , const void * val_buf , size_t val_size )
@@ -231,14 +172,26 @@ static int cs35l56_sdw_write(void *context, const void *val_buf, size_t val_size
231172 * byte controls always have the same byte order, and firmware file blobs
232173 * can be written verbatim.
233174 */
234- static const struct regmap_bus cs35l56_regmap_bus_sdw = {
175+ static const struct regmap_bus cs35l56_regmap_swab_bus_sdw = {
235176 .read = cs35l56_sdw_read ,
236177 .write = cs35l56_sdw_write ,
237178 .gather_write = cs35l56_sdw_gather_write ,
238179 .reg_format_endian_default = REGMAP_ENDIAN_LITTLE ,
239180 .val_format_endian_default = REGMAP_ENDIAN_BIG ,
240181};
241182
183+ /* Low-level SoundWire regmap to transfer the data over the bus */
184+ static const struct regmap_config cs35l56_sdw_bus_regmap = {
185+ .name = "sdw-le32" ,
186+ .reg_bits = 32 ,
187+ .val_bits = 32 ,
188+ .reg_stride = 4 ,
189+ .reg_format_endian = REGMAP_ENDIAN_LITTLE ,
190+ .val_format_endian = REGMAP_ENDIAN_LITTLE ,
191+ .max_register = CS35L56_DSP1_PMEM_5114 + 0x8000 ,
192+ .cache_type = REGCACHE_NONE ,
193+ };
194+
242195static int cs35l56_sdw_get_unique_id (struct cs35l56_private * cs35l56 )
243196{
244197 int ret ;
@@ -560,8 +513,16 @@ static int cs35l56_sdw_probe(struct sdw_slave *peripheral, const struct sdw_devi
560513
561514 cs35l56 -> base .type = ((unsigned int )id -> driver_data ) & 0xff ;
562515
563- cs35l56 -> base .regmap = devm_regmap_init (dev , & cs35l56_regmap_bus_sdw ,
564- peripheral , regmap_config );
516+ /* Low-level regmap to transfer read/writes over SoundWire bus */
517+ cs35l56 -> sdw_bus_regmap = devm_regmap_init_sdw (peripheral , & cs35l56_sdw_bus_regmap );
518+ if (IS_ERR (cs35l56 -> sdw_bus_regmap )) {
519+ ret = PTR_ERR (cs35l56 -> sdw_bus_regmap );
520+ return dev_err_probe (dev , ret , "Failed to allocate bus register map\n" );
521+ }
522+
523+ /* Wrapper regmap to simulate big-endian ordering */
524+ cs35l56 -> base .regmap = devm_regmap_init (dev , & cs35l56_regmap_swab_bus_sdw ,
525+ peripheral , regmap_config );
565526 if (IS_ERR (cs35l56 -> base .regmap )) {
566527 ret = PTR_ERR (cs35l56 -> base .regmap );
567528 return dev_err_probe (dev , ret , "Failed to allocate register map\n" );
0 commit comments