@@ -2168,6 +2168,184 @@ static const struct of_device_id wm8904_of_match[] = {
2168
2168
MODULE_DEVICE_TABLE (of , wm8904_of_match );
2169
2169
#endif
2170
2170
2171
+ /**
2172
+ * wm8904_read_cfg_reg_arr() - Reads a subarray from a DT u16 array
2173
+ *
2174
+ * @np: pointer to the device_node struct
2175
+ * @regs_property: DT property of interest
2176
+ * @size: size of subarrays within the array
2177
+ * @idx: index of the subarray of interest
2178
+ * @out: output
2179
+ *
2180
+ * Helper to read a subarray from a DT uint16-array,
2181
+ * divided into equally sized arrays of size `size`
2182
+ *
2183
+ * Subset starts at `idx * size` and is of size `size`
2184
+ *
2185
+ * Return: 0 on success, negative error code otherwise
2186
+ */
2187
+ static int wm8904_read_cfg_reg_arr (const struct device_node * np ,
2188
+ const char * const regs_property ,
2189
+ int size , int idx ,
2190
+ u16 * const out )
2191
+ {
2192
+ int i , offset , ret ;
2193
+
2194
+ offset = idx * size ;
2195
+
2196
+ for (i = 0 ; i < size ; i ++ ) {
2197
+ ret = of_property_read_u16_index (np , regs_property , i + offset , & out [i ]);
2198
+ if (ret )
2199
+ return ret ;
2200
+ }
2201
+ return 0 ;
2202
+ }
2203
+
2204
+ static int wm8904_parse_retune_cfg_regs (const struct device_node * np ,
2205
+ struct wm8904_pdata * pdata , int cfg_idx )
2206
+ {
2207
+ return wm8904_read_cfg_reg_arr (np , "wlf,retune-mobile-cfg-regs" ,
2208
+ WM8904_EQ_REGS , cfg_idx ,
2209
+ & pdata -> retune_mobile_cfgs [cfg_idx ].regs [0 ]);
2210
+ }
2211
+
2212
+ static int wm8904_parse_drc_cfg_regs (const struct device_node * np ,
2213
+ struct wm8904_pdata * pdata , int cfg_idx )
2214
+ {
2215
+ return wm8904_read_cfg_reg_arr (np , "wlf,drc-cfg-regs" ,
2216
+ WM8904_DRC_REGS , cfg_idx ,
2217
+ & pdata -> drc_cfgs [cfg_idx ].regs [0 ]);
2218
+ }
2219
+
2220
+ static int wm8904_parse_drc_cfg_from_of (struct i2c_client * i2c ,
2221
+ struct wm8904_pdata * pdata )
2222
+ {
2223
+ const struct device_node * np = i2c -> dev .of_node ;
2224
+ int i , n_cfgs ;
2225
+
2226
+ n_cfgs = of_property_count_strings (np , "wlf,drc-cfg-names" );
2227
+ if (n_cfgs == - EINVAL )
2228
+ return 0 ;
2229
+
2230
+ if (n_cfgs <= 0 ) {
2231
+ dev_err (& i2c -> dev , "Could not get wlf,drc-cfg-names length: %d" ,
2232
+ n_cfgs );
2233
+ return n_cfgs ;
2234
+ }
2235
+
2236
+ pdata -> drc_cfgs = devm_kzalloc (& i2c -> dev ,
2237
+ n_cfgs * sizeof (struct wm8904_drc_cfg ),
2238
+ GFP_KERNEL );
2239
+ if (!pdata -> drc_cfgs )
2240
+ return - ENOMEM ;
2241
+
2242
+ for (i = 0 ; i < n_cfgs ; i ++ ) {
2243
+ if (wm8904_parse_drc_cfg_regs (np , pdata , i )) {
2244
+ dev_err (& i2c -> dev ,
2245
+ "Invalid 'wlf,drc-cfg-regs[%i,:]'\n" , i );
2246
+ return - EINVAL ;
2247
+ }
2248
+
2249
+ if (of_property_read_string_index (np , "wlf,drc-cfg-names" , i ,
2250
+ & pdata -> drc_cfgs [i ].name )) {
2251
+ dev_err (& i2c -> dev ,
2252
+ "Invalid 'wlf,drc-cfg-names[%i]'\n" , i );
2253
+ return - EINVAL ;
2254
+ }
2255
+ }
2256
+
2257
+ pdata -> num_drc_cfgs = n_cfgs ;
2258
+ return 0 ;
2259
+ }
2260
+
2261
+ static int wm8904_parse_retune_cfg_from_of (struct i2c_client * i2c ,
2262
+ struct wm8904_pdata * pdata )
2263
+ {
2264
+ const struct device_node * np = i2c -> dev .of_node ;
2265
+ int i , n_cfgs ;
2266
+
2267
+ n_cfgs = of_property_count_strings (np , "wlf,retune-mobile-cfg-names" );
2268
+ if (n_cfgs == - EINVAL )
2269
+ return 0 ;
2270
+
2271
+ if (n_cfgs <= 0 ) {
2272
+ dev_err (& i2c -> dev ,
2273
+ "Could not get wlf,retune-mobile-cfg-names length: %d" ,
2274
+ n_cfgs );
2275
+ return n_cfgs ;
2276
+ }
2277
+
2278
+ pdata -> retune_mobile_cfgs = devm_kzalloc (& i2c -> dev ,
2279
+ n_cfgs * sizeof (struct wm8904_retune_mobile_cfg ),
2280
+ GFP_KERNEL );
2281
+ if (!pdata -> retune_mobile_cfgs )
2282
+ return - ENOMEM ;
2283
+
2284
+ for (i = 0 ; i < n_cfgs ; i ++ ) {
2285
+ if (wm8904_parse_retune_cfg_regs (np , pdata , i )) {
2286
+ dev_err (& i2c -> dev ,
2287
+ "Invalid 'wlf,retune-mobile-cfg-regs[%i,:]'\n" , i );
2288
+ return - EINVAL ;
2289
+ }
2290
+
2291
+ if (of_property_read_u32_index (np , "wlf,retune-mobile-cfg-hz" , i ,
2292
+ & pdata -> retune_mobile_cfgs [i ].rate )) {
2293
+ dev_err (& i2c -> dev ,
2294
+ "Invalid 'wlf,retune-mobile-cfg-hz[%i]'\n" , i );
2295
+ return - EINVAL ;
2296
+ }
2297
+
2298
+ if (of_property_read_string_index (np , "wlf,retune-mobile-cfg-names" , i ,
2299
+ & pdata -> retune_mobile_cfgs [i ].name )) {
2300
+ dev_err (& i2c -> dev ,
2301
+ "Invalid 'wlf,retune-mobile-cfg-names[%i]'\n" , i );
2302
+ return - EINVAL ;
2303
+ }
2304
+ }
2305
+
2306
+ pdata -> num_retune_mobile_cfgs = n_cfgs ;
2307
+ return 0 ;
2308
+ }
2309
+
2310
+ static int wm8904_set_pdata_from_of (struct i2c_client * i2c ,
2311
+ struct wm8904_priv * wm8904 )
2312
+ {
2313
+ const struct device_node * np = i2c -> dev .of_node ;
2314
+ struct wm8904_pdata * pdata ;
2315
+ int ret , i ;
2316
+
2317
+ pdata = devm_kzalloc (& i2c -> dev , sizeof (* pdata ), GFP_KERNEL );
2318
+ if (!pdata )
2319
+ return - ENOMEM ;
2320
+
2321
+ pdata -> in1l_as_dmicdat1 =
2322
+ of_property_read_bool (np , "wlf,in1l-as-dmicdat1" );
2323
+
2324
+ pdata -> in1r_as_dmicdat2 =
2325
+ of_property_read_bool (np , "wlf,in1r-as-dmicdat2" );
2326
+
2327
+ /* If absent, default to 0xFFFF for GPIO config (i.e.: don't set) */
2328
+ for (i = 0 ; i < WM8904_GPIO_REGS ; i ++ )
2329
+ pdata -> gpio_cfg [i ] = 0xFFFF ;
2330
+
2331
+ of_property_read_u32_array (np , "wlf,gpio-cfg" , pdata -> gpio_cfg ,
2332
+ ARRAY_SIZE (pdata -> gpio_cfg ));
2333
+
2334
+ of_property_read_u32_array (np , "wlf,micbias-cfg" , pdata -> mic_cfg ,
2335
+ ARRAY_SIZE (pdata -> mic_cfg ));
2336
+
2337
+ ret = wm8904_parse_drc_cfg_from_of (i2c , pdata );
2338
+ if (ret )
2339
+ return ret ;
2340
+
2341
+ ret = wm8904_parse_retune_cfg_from_of (i2c , pdata );
2342
+ if (ret )
2343
+ return ret ;
2344
+
2345
+ wm8904 -> pdata = pdata ;
2346
+ return 0 ;
2347
+ }
2348
+
2171
2349
static const struct i2c_device_id wm8904_i2c_id [];
2172
2350
2173
2351
static int wm8904_i2c_probe (struct i2c_client * i2c )
@@ -2199,7 +2377,16 @@ static int wm8904_i2c_probe(struct i2c_client *i2c)
2199
2377
wm8904 -> devtype = (uintptr_t )i2c_get_match_data (i2c );
2200
2378
2201
2379
i2c_set_clientdata (i2c , wm8904 );
2202
- wm8904 -> pdata = i2c -> dev .platform_data ;
2380
+
2381
+ if (i2c -> dev .of_node ) {
2382
+ ret = wm8904_set_pdata_from_of (i2c , wm8904 );
2383
+ if (ret ) {
2384
+ dev_err (& i2c -> dev , "Failed to set platform data from of: %d\n" , ret );
2385
+ return ret ;
2386
+ }
2387
+ } else {
2388
+ wm8904 -> pdata = i2c -> dev .platform_data ;
2389
+ }
2203
2390
2204
2391
for (i = 0 ; i < ARRAY_SIZE (wm8904 -> supplies ); i ++ )
2205
2392
wm8904 -> supplies [i ].supply = wm8904_supply_names [i ];
0 commit comments