@@ -76,6 +76,19 @@ static int si2157_cmd_execute(struct i2c_client *client, struct si2157_cmd *cmd)
76
76
return ret ;
77
77
}
78
78
79
+ static const struct si2157_tuner_info si2157_tuners [] = {
80
+ { SI2141 , false, 0x60 , SI2141_60_FIRMWARE , SI2141_A10_FIRMWARE },
81
+ { SI2141 , false, 0x61 , SI2141_61_FIRMWARE , SI2141_A10_FIRMWARE },
82
+ { SI2146 , false, 0x11 , SI2146_11_FIRMWARE , NULL },
83
+ { SI2147 , false, 0x50 , SI2147_50_FIRMWARE , NULL },
84
+ { SI2148 , true, 0x32 , SI2148_32_FIRMWARE , SI2158_A20_FIRMWARE },
85
+ { SI2148 , true, 0x33 , SI2148_33_FIRMWARE , SI2158_A20_FIRMWARE },
86
+ { SI2157 , false, 0x50 , SI2157_50_FIRMWARE , SI2157_A30_FIRMWARE },
87
+ { SI2158 , false, 0x50 , SI2158_50_FIRMWARE , SI2158_A20_FIRMWARE },
88
+ { SI2158 , false, 0x51 , SI2158_51_FIRMWARE , SI2158_A20_FIRMWARE },
89
+ { SI2177 , false, 0x50 , SI2177_50_FIRMWARE , SI2157_A30_FIRMWARE },
90
+ };
91
+
79
92
static int si2157_load_firmware (struct dvb_frontend * fe ,
80
93
const char * fw_name )
81
94
{
@@ -85,7 +98,7 @@ static int si2157_load_firmware(struct dvb_frontend *fe,
85
98
struct si2157_cmd cmd ;
86
99
87
100
/* request the firmware, this will block and timeout */
88
- ret = request_firmware (& fw , fw_name , & client -> dev );
101
+ ret = firmware_request_nowarn (& fw , fw_name , & client -> dev );
89
102
if (ret )
90
103
return ret ;
91
104
@@ -124,16 +137,86 @@ static int si2157_load_firmware(struct dvb_frontend *fe,
124
137
return ret ;
125
138
}
126
139
140
+ static int si2157_find_and_load_firmware (struct dvb_frontend * fe )
141
+ {
142
+ struct i2c_client * client = fe -> tuner_priv ;
143
+ struct si2157_dev * dev = i2c_get_clientdata (client );
144
+ const char * fw_alt_name = NULL ;
145
+ unsigned char part_id , rom_id ;
146
+ const char * fw_name = NULL ;
147
+ struct si2157_cmd cmd ;
148
+ bool required = true;
149
+ int ret , i ;
150
+
151
+ if (dev -> dont_load_firmware ) {
152
+ dev_info (& client -> dev ,
153
+ "device is buggy, skipping firmware download\n" );
154
+ return 0 ;
155
+ }
156
+
157
+ /* query chip revision */
158
+ memcpy (cmd .args , "\x02" , 1 );
159
+ cmd .wlen = 1 ;
160
+ cmd .rlen = 13 ;
161
+ ret = si2157_cmd_execute (client , & cmd );
162
+ if (ret )
163
+ return ret ;
164
+
165
+ part_id = cmd .args [2 ];
166
+ rom_id = cmd .args [12 ];
167
+
168
+ for (i = 0 ; i < ARRAY_SIZE (si2157_tuners ); i ++ ) {
169
+ if (si2157_tuners [i ].part_id != part_id )
170
+ continue ;
171
+ required = si2157_tuners [i ].required ;
172
+ fw_alt_name = si2157_tuners [i ].fw_alt_name ;
173
+
174
+ /* Both part and rom ID match */
175
+ if (si2157_tuners [i ].rom_id == rom_id ) {
176
+ fw_name = si2157_tuners [i ].fw_name ;
177
+ break ;
178
+ }
179
+ }
180
+
181
+ if (!fw_name && !fw_alt_name ) {
182
+ dev_err (& client -> dev ,
183
+ "unknown chip version Si21%d-%c%c%c ROM 0x%02x\n" ,
184
+ part_id , cmd .args [1 ], cmd .args [3 ], cmd .args [4 ], rom_id );
185
+ return - EINVAL ;
186
+ }
187
+
188
+ dev_info (& client -> dev ,
189
+ "found a 'Silicon Labs Si21%d-%c%c%c ROM 0x%02x'\n" ,
190
+ part_id , cmd .args [1 ], cmd .args [3 ], cmd .args [4 ], rom_id );
191
+
192
+ if (fw_name )
193
+ ret = si2157_load_firmware (fe , fw_name );
194
+ else
195
+ ret = - ENOENT ;
196
+
197
+ /* Try alternate name, if any */
198
+ if (ret == - ENOENT && fw_alt_name )
199
+ ret = si2157_load_firmware (fe , fw_alt_name );
200
+
201
+ if (ret == - ENOENT ) {
202
+ if (!required ) {
203
+ dev_info (& client -> dev , "Using ROM firmware.\n" );
204
+ return 0 ;
205
+ }
206
+ dev_err (& client -> dev , "Can't continue without a firmware.\n" );
207
+ } else if (ret < 0 ) {
208
+ dev_err (& client -> dev , "error %d when loading firmware\n" , ret );
209
+ }
210
+ return ret ;
211
+ }
212
+
127
213
static int si2157_init (struct dvb_frontend * fe )
128
214
{
129
215
struct dtv_frontend_properties * c = & fe -> dtv_property_cache ;
130
216
struct i2c_client * client = fe -> tuner_priv ;
131
217
struct si2157_dev * dev = i2c_get_clientdata (client );
132
- bool warn_firmware_not_loaded = false;
133
- unsigned int chip_id , xtal_trim ;
134
- bool fw_required = true;
218
+ unsigned int xtal_trim ;
135
219
struct si2157_cmd cmd ;
136
- const char * fw_name ;
137
220
int ret ;
138
221
139
222
dev_dbg (& client -> dev , "\n" );
@@ -176,72 +259,11 @@ static int si2157_init(struct dvb_frontend *fe)
176
259
goto err ;
177
260
}
178
261
179
- if (dev -> dont_load_firmware ) {
180
- dev_info (& client -> dev , "device is buggy, skipping firmware download\n" );
181
- goto skip_fw_download ;
182
- }
183
-
184
- /* query chip revision */
185
- memcpy (cmd .args , "\x02" , 1 );
186
- cmd .wlen = 1 ;
187
- cmd .rlen = 13 ;
188
- ret = si2157_cmd_execute (client , & cmd );
189
- if (ret )
262
+ /* Try to load the firmware */
263
+ ret = si2157_find_and_load_firmware (fe );
264
+ if (ret < 0 )
190
265
goto err ;
191
266
192
- chip_id = cmd .args [1 ] << 24 | cmd .args [2 ] << 16 | cmd .args [3 ] << 8 |
193
- cmd .args [4 ] << 0 ;
194
-
195
- #define SI2177_A30 ('A' << 24 | 77 << 16 | '3' << 8 | '0' << 0)
196
- #define SI2158_A20 ('A' << 24 | 58 << 16 | '2' << 8 | '0' << 0)
197
- #define SI2148_A20 ('A' << 24 | 48 << 16 | '2' << 8 | '0' << 0)
198
- #define SI2157_A30 ('A' << 24 | 57 << 16 | '3' << 8 | '0' << 0)
199
- #define SI2147_A30 ('A' << 24 | 47 << 16 | '3' << 8 | '0' << 0)
200
- #define SI2146_A10 ('A' << 24 | 46 << 16 | '1' << 8 | '0' << 0)
201
- #define SI2141_A10 ('A' << 24 | 41 << 16 | '1' << 8 | '0' << 0)
202
-
203
- switch (chip_id ) {
204
- case SI2158_A20 :
205
- case SI2148_A20 :
206
- fw_name = SI2158_A20_FIRMWARE ;
207
- break ;
208
- case SI2141_A10 :
209
- fw_name = SI2141_A10_FIRMWARE ;
210
- break ;
211
- case SI2157_A30 :
212
- fw_required = false;
213
- fallthrough ;
214
- case SI2177_A30 :
215
- fw_name = SI2157_A30_FIRMWARE ;
216
- break ;
217
- case SI2147_A30 :
218
- case SI2146_A10 :
219
- fw_name = NULL ;
220
- break ;
221
- default :
222
- dev_err (& client -> dev , "unknown chip version Si21%d-%c%c%c\n" ,
223
- cmd .args [2 ], cmd .args [1 ],
224
- cmd .args [3 ], cmd .args [4 ]);
225
- ret = - EINVAL ;
226
- goto err ;
227
- }
228
-
229
- dev_info (& client -> dev , "found a 'Silicon Labs Si21%d-%c%c%c'\n" ,
230
- cmd .args [2 ], cmd .args [1 ], cmd .args [3 ], cmd .args [4 ]);
231
-
232
- if (fw_name == NULL )
233
- goto skip_fw_download ;
234
-
235
- ret = si2157_load_firmware (fe , fw_name );
236
- if (fw_required && ret == - ENOENT )
237
- warn_firmware_not_loaded = true;
238
- else if (ret < 0 ) {
239
- dev_err (& client -> dev , "error %d when loading firmware file '%s'\n" ,
240
- ret , fw_name );
241
- goto err ;
242
- }
243
-
244
- skip_fw_download :
245
267
/* reboot the tuner with new firmware? */
246
268
memcpy (cmd .args , "\x01\x01" , 2 );
247
269
cmd .wlen = 2 ;
@@ -258,11 +280,6 @@ static int si2157_init(struct dvb_frontend *fe)
258
280
if (ret )
259
281
goto err ;
260
282
261
- if (warn_firmware_not_loaded ) {
262
- dev_warn (& client -> dev , "firmware file '%s' not found. Using firmware from eeprom.\n" ,
263
- fw_name );
264
- warn_firmware_not_loaded = false;
265
- }
266
283
dev_info (& client -> dev , "firmware version: %c.%c.%d\n" ,
267
284
cmd .args [6 ], cmd .args [7 ], cmd .args [8 ]);
268
285
@@ -298,11 +315,6 @@ static int si2157_init(struct dvb_frontend *fe)
298
315
return 0 ;
299
316
300
317
err :
301
- if (warn_firmware_not_loaded )
302
- dev_err (& client -> dev ,
303
- "firmware file '%s' not found. Can't continue without a firmware.\n" ,
304
- fw_name );
305
-
306
318
dev_dbg (& client -> dev , "failed=%d\n" , ret );
307
319
return ret ;
308
320
}
@@ -968,3 +980,13 @@ MODULE_LICENSE("GPL");
968
980
MODULE_FIRMWARE (SI2158_A20_FIRMWARE );
969
981
MODULE_FIRMWARE (SI2141_A10_FIRMWARE );
970
982
MODULE_FIRMWARE (SI2157_A30_FIRMWARE );
983
+ MODULE_FIRMWARE (SI2141_60_FIRMWARE );
984
+ MODULE_FIRMWARE (SI2141_61_FIRMWARE );
985
+ MODULE_FIRMWARE (SI2146_11_FIRMWARE );
986
+ MODULE_FIRMWARE (SI2147_50_FIRMWARE );
987
+ MODULE_FIRMWARE (SI2148_32_FIRMWARE );
988
+ MODULE_FIRMWARE (SI2148_33_FIRMWARE );
989
+ MODULE_FIRMWARE (SI2157_50_FIRMWARE );
990
+ MODULE_FIRMWARE (SI2158_50_FIRMWARE );
991
+ MODULE_FIRMWARE (SI2158_51_FIRMWARE );
992
+ MODULE_FIRMWARE (SI2177_50_FIRMWARE );
0 commit comments