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"
@@ -95,55 +96,23 @@ static int cs35l56_sdw_slow_read(struct sdw_slave *peripheral, unsigned int reg,
9596 return 0 ;
9697}
9798
98- static int cs35l56_sdw_read_one (struct sdw_slave * peripheral , unsigned int reg , void * buf )
99- {
100- int ret ;
101-
102- ret = sdw_nread_no_pm (peripheral , reg , 4 , (u8 * )buf );
103- if (ret != 0 ) {
104- dev_err (& peripheral -> dev , "Read failed @%#x:%d\n" , reg , ret );
105- return ret ;
106- }
107-
108- swab32s ((u32 * )buf );
109-
110- return 0 ;
111- }
112-
11399static int cs35l56_sdw_read (void * context , const void * reg_buf ,
114100 const size_t reg_size , void * val_buf ,
115101 size_t val_size )
116102{
117103 struct sdw_slave * peripheral = context ;
118- u8 * buf8 = val_buf ;
119- unsigned int reg , bytes ;
104+ struct cs35l56_private * cs35l56 = dev_get_drvdata ( & peripheral -> dev ) ;
105+ unsigned int reg_addr = get_unaligned_le32 ( reg_buf ) ;
120106 int ret ;
121107
122- 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 );
123110
124- if (cs35l56_is_otp_register (reg - CS35L56_SDW_ADDR_OFFSET ))
125- return cs35l56_sdw_slow_read (peripheral , reg , buf8 , val_size );
126-
127- if (val_size == 4 )
128- return cs35l56_sdw_read_one (peripheral , reg , val_buf );
129-
130- while (val_size ) {
131- bytes = SDW_REG_NO_PAGE - (reg & SDW_REGADDR ); /* to end of page */
132- if (bytes > val_size )
133- bytes = val_size ;
134-
135- ret = sdw_nread_no_pm (peripheral , reg , bytes , buf8 );
136- if (ret != 0 ) {
137- dev_err (& peripheral -> dev , "Read failed @%#x..%#x:%d\n" ,
138- reg , reg + bytes - 1 , ret );
139- return ret ;
140- }
111+ ret = regmap_raw_read (cs35l56 -> sdw_bus_regmap , reg_addr , val_buf , val_size );
112+ if (ret )
113+ return ret ;
141114
142- swab32_array ((u32 * )buf8 , bytes / 4 );
143- val_size -= bytes ;
144- reg += bytes ;
145- buf8 += bytes ;
146- }
115+ swab32_array ((u32 * )val_buf , val_size / sizeof (u32 ));
147116
148117 return 0 ;
149118}
@@ -157,57 +126,34 @@ static inline void cs35l56_swab_copy(void *dest, const void *src, size_t nbytes)
157126 * dest32 ++ = swab32 (* src32 ++ );
158127}
159128
160- static int cs35l56_sdw_write_one (struct sdw_slave * peripheral , unsigned int reg , const void * buf )
161- {
162- u32 val_le = swab32 (* (u32 * )buf );
163- int ret ;
164-
165- ret = sdw_nwrite_no_pm (peripheral , reg , 4 , (u8 * )& val_le );
166- if (ret != 0 ) {
167- dev_err (& peripheral -> dev , "Write failed @%#x:%d\n" , reg , ret );
168- return ret ;
169- }
170-
171- return 0 ;
172- }
173-
174129static int cs35l56_sdw_gather_write (void * context ,
175130 const void * reg_buf , size_t reg_size ,
176131 const void * val_buf , size_t val_size )
177132{
178133 struct sdw_slave * peripheral = context ;
179- const u8 * src_be = val_buf ;
180- u32 val_le_buf [ 64 ]; /* Define u32 so it is 32-bit aligned */
181- 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 */
182137 int ret ;
183138
184- reg = le32_to_cpu (* (const __le32 * )reg_buf );
185-
186- if (val_size == 4 )
187- return cs35l56_sdw_write_one (peripheral , reg , src_be );
188-
189- while (val_size ) {
190- bytes = SDW_REG_NO_PAGE - (reg & SDW_REGADDR ); /* to end of page */
191- if (bytes > val_size )
192- bytes = val_size ;
193- if (bytes > sizeof (val_le_buf ))
194- bytes = sizeof (val_le_buf );
195-
196- cs35l56_swab_copy (val_le_buf , src_be , bytes );
197-
198- ret = sdw_nwrite_no_pm (peripheral , reg , bytes , (u8 * )val_le_buf );
199- if (ret != 0 ) {
200- dev_err (& peripheral -> dev , "Write failed @%#x..%#x:%d\n" ,
201- 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 )
202144 return ret ;
203- }
204145
205- val_size -= bytes ;
206- reg += bytes ;
207- src_be += bytes ;
146+ val_size -= sizeof ( swab_buf ) ;
147+ reg_addr += sizeof ( swab_buf ) ;
148+ val_buf += sizeof ( swab_buf ) ;
208149 }
209150
210- 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 );
211157}
212158
213159static int cs35l56_sdw_write (void * context , const void * val_buf , size_t val_size )
@@ -226,14 +172,26 @@ static int cs35l56_sdw_write(void *context, const void *val_buf, size_t val_size
226172 * byte controls always have the same byte order, and firmware file blobs
227173 * can be written verbatim.
228174 */
229- static const struct regmap_bus cs35l56_regmap_bus_sdw = {
175+ static const struct regmap_bus cs35l56_regmap_swab_bus_sdw = {
230176 .read = cs35l56_sdw_read ,
231177 .write = cs35l56_sdw_write ,
232178 .gather_write = cs35l56_sdw_gather_write ,
233179 .reg_format_endian_default = REGMAP_ENDIAN_LITTLE ,
234180 .val_format_endian_default = REGMAP_ENDIAN_BIG ,
235181};
236182
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+
237195static int cs35l56_sdw_get_unique_id (struct cs35l56_private * cs35l56 )
238196{
239197 int ret ;
@@ -555,8 +513,16 @@ static int cs35l56_sdw_probe(struct sdw_slave *peripheral, const struct sdw_devi
555513
556514 cs35l56 -> base .type = ((unsigned int )id -> driver_data ) & 0xff ;
557515
558- cs35l56 -> base .regmap = devm_regmap_init (dev , & cs35l56_regmap_bus_sdw ,
559- 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 );
560526 if (IS_ERR (cs35l56 -> base .regmap )) {
561527 ret = PTR_ERR (cs35l56 -> base .regmap );
562528 return dev_err_probe (dev , ret , "Failed to allocate register map\n" );
0 commit comments