@@ -76,16 +76,63 @@ static int si2157_cmd_execute(struct i2c_client *client, struct si2157_cmd *cmd)
76
76
return ret ;
77
77
}
78
78
79
+ static int si2157_load_firmware (struct dvb_frontend * fe ,
80
+ const char * fw_name )
81
+ {
82
+ struct i2c_client * client = fe -> tuner_priv ;
83
+ const struct firmware * fw ;
84
+ int ret , len , remaining ;
85
+ struct si2157_cmd cmd ;
86
+
87
+ /* request the firmware, this will block and timeout */
88
+ ret = request_firmware (& fw , fw_name , & client -> dev );
89
+ if (ret )
90
+ return ret ;
91
+
92
+ /* firmware should be n chunks of 17 bytes */
93
+ if (fw -> size % 17 != 0 ) {
94
+ dev_err (& client -> dev , "firmware file '%s' is invalid\n" ,
95
+ fw_name );
96
+ ret = - EINVAL ;
97
+ goto err_release_firmware ;
98
+ }
99
+
100
+ dev_info (& client -> dev , "downloading firmware from file '%s'\n" ,
101
+ fw_name );
102
+
103
+ for (remaining = fw -> size ; remaining > 0 ; remaining -= 17 ) {
104
+ len = fw -> data [fw -> size - remaining ];
105
+ if (len > SI2157_ARGLEN ) {
106
+ dev_err (& client -> dev , "Bad firmware length\n" );
107
+ ret = - EINVAL ;
108
+ goto err_release_firmware ;
109
+ }
110
+ memcpy (cmd .args , & fw -> data [(fw -> size - remaining ) + 1 ], len );
111
+ cmd .wlen = len ;
112
+ cmd .rlen = 1 ;
113
+ ret = si2157_cmd_execute (client , & cmd );
114
+ if (ret ) {
115
+ dev_err (& client -> dev , "firmware download failed %d\n" ,
116
+ ret );
117
+ goto err_release_firmware ;
118
+ }
119
+ }
120
+
121
+ err_release_firmware :
122
+ release_firmware (fw );
123
+
124
+ return ret ;
125
+ }
126
+
79
127
static int si2157_init (struct dvb_frontend * fe )
80
128
{
129
+ struct dtv_frontend_properties * c = & fe -> dtv_property_cache ;
81
130
struct i2c_client * client = fe -> tuner_priv ;
82
131
struct si2157_dev * dev = i2c_get_clientdata (client );
83
- struct dtv_frontend_properties * c = & fe -> dtv_property_cache ;
84
- int ret , len , remaining ;
132
+ unsigned int chip_id , xtal_trim ;
85
133
struct si2157_cmd cmd ;
86
- const struct firmware * fw ;
87
134
const char * fw_name ;
88
- unsigned int chip_id , xtal_trim ;
135
+ int ret ;
89
136
90
137
dev_dbg (& client -> dev , "\n" );
91
138
@@ -181,45 +228,13 @@ static int si2157_init(struct dvb_frontend *fe)
181
228
if (fw_name == NULL )
182
229
goto skip_fw_download ;
183
230
184
- /* request the firmware, this will block and timeout */
185
- ret = request_firmware (& fw , fw_name , & client -> dev );
231
+ ret = si2157_load_firmware (fe , fw_name );
186
232
if (ret ) {
187
233
dev_err (& client -> dev , "firmware file '%s' not found\n" ,
188
- fw_name );
189
- goto err ;
190
- }
191
-
192
- /* firmware should be n chunks of 17 bytes */
193
- if (fw -> size % 17 != 0 ) {
194
- dev_err (& client -> dev , "firmware file '%s' is invalid\n" ,
195
- fw_name );
196
- ret = - EINVAL ;
197
- goto err_release_firmware ;
198
- }
199
-
200
- dev_info (& client -> dev , "downloading firmware from file '%s'\n" ,
201
234
fw_name );
202
-
203
- for (remaining = fw -> size ; remaining > 0 ; remaining -= 17 ) {
204
- len = fw -> data [fw -> size - remaining ];
205
- if (len > SI2157_ARGLEN ) {
206
- dev_err (& client -> dev , "Bad firmware length\n" );
207
- ret = - EINVAL ;
208
- goto err_release_firmware ;
209
- }
210
- memcpy (cmd .args , & fw -> data [(fw -> size - remaining ) + 1 ], len );
211
- cmd .wlen = len ;
212
- cmd .rlen = 1 ;
213
- ret = si2157_cmd_execute (client , & cmd );
214
- if (ret ) {
215
- dev_err (& client -> dev , "firmware download failed %d\n" ,
216
- ret );
217
- goto err_release_firmware ;
218
- }
235
+ goto err ;
219
236
}
220
237
221
- release_firmware (fw );
222
-
223
238
skip_fw_download :
224
239
/* reboot the tuner with new firmware? */
225
240
memcpy (cmd .args , "\x01\x01" , 2 );
@@ -270,8 +285,7 @@ static int si2157_init(struct dvb_frontend *fe)
270
285
271
286
dev -> active = true;
272
287
return 0 ;
273
- err_release_firmware :
274
- release_firmware (fw );
288
+
275
289
err :
276
290
dev_dbg (& client -> dev , "failed=%d\n" , ret );
277
291
return ret ;
0 commit comments