197 {2, EC_DIR_OUTPUT, 2, el6002_pdos + 0, EC_WD_DISABLE}, |
200 {2, EC_DIR_OUTPUT, 2, el6002_pdos + 0, EC_WD_DISABLE}, |
198 {3, EC_DIR_INPUT, 2, el6002_pdos + 2, EC_WD_DISABLE}, |
201 {3, EC_DIR_INPUT, 2, el6002_pdos + 2, EC_WD_DISABLE}, |
199 {0xff} |
202 {0xff} |
200 }; |
203 }; |
201 |
204 |
|
205 typedef enum { |
|
206 PAR_NONE, |
|
207 PAR_ODD, |
|
208 PAR_EVEN |
|
209 } parity_t; |
|
210 |
|
211 typedef struct { |
|
212 u8 value; |
|
213 unsigned short data_bits; |
|
214 parity_t parity; |
|
215 unsigned short stop_bits; |
|
216 } el600x_data_frame_t; |
|
217 |
|
218 /** EL600x supported values for SDO 4074. |
|
219 */ |
|
220 el600x_data_frame_t el600x_data_frame[] = { |
|
221 {0x01, 7, PAR_EVEN, 1}, |
|
222 {0x09, 7, PAR_EVEN, 2}, |
|
223 {0x02, 7, PAR_ODD, 1}, |
|
224 {0x0a, 7, PAR_ODD, 2}, |
|
225 {0x03, 8, PAR_NONE, 1}, |
|
226 {0x0b, 8, PAR_NONE, 2}, |
|
227 {0x04, 8, PAR_EVEN, 1}, |
|
228 {0x0c, 8, PAR_EVEN, 2}, |
|
229 {0x05, 8, PAR_ODD, 1}, |
|
230 {0x0d, 8, PAR_ODD, 2}, |
|
231 }; |
|
232 |
202 /****************************************************************************/ |
233 /****************************************************************************/ |
203 |
234 |
204 int el6002_cflag_changed(void *data, unsigned short cflag) |
235 int el6002_cflag_changed(void *data, unsigned short cflag) |
205 { |
236 { |
206 el6002_t *ser = (el6002_t *) data; |
237 el6002_t *ser = (el6002_t *) data; |
207 int cs = 0, stop, par; |
238 unsigned short data_bits, stop_bits; |
|
239 parity_t par; |
|
240 unsigned int i; |
|
241 el600x_data_frame_t *df_to_use = NULL; |
208 |
242 |
209 printk(KERN_INFO PFX "%s(data=%p, cflag=%x).\n", __func__, ser, cflag); |
243 printk(KERN_INFO PFX "%s(data=%p, cflag=%x).\n", __func__, ser, cflag); |
210 |
244 |
211 switch (cflag & CSIZE) { |
245 switch (cflag & CSIZE) { |
|
246 case CS5: |
|
247 data_bits = 5; |
|
248 break; |
|
249 case CS6: |
|
250 data_bits = 6; |
|
251 break; |
212 case CS7: |
252 case CS7: |
213 cs = 7; |
253 data_bits = 7; |
214 break; |
254 break; |
215 case CS8: |
255 case CS8: |
216 cs = 8; |
256 data_bits = 8; |
217 break; |
257 break; |
218 default: /* CS5 or CS6 */ |
258 default: /* CS5 or CS6 */ |
219 return -EINVAL; // not supported |
259 data_bits = 0; |
220 } |
260 } |
221 |
|
222 stop = (cflag & CSTOPB) ? 2 : 1; |
|
223 |
261 |
224 if (cflag & PARENB) { |
262 if (cflag & PARENB) { |
225 par = (cflag & PARODD) ? 1 : 2; |
263 par = (cflag & PARODD) ? PAR_ODD : PAR_EVEN; |
226 } else { |
264 } else { |
227 par = 0; |
265 par = PAR_NONE; |
228 } |
266 } |
229 |
267 |
230 printk(KERN_INFO PFX "CS%u stopb=%u par=%i.\n", cs, stop, par); |
268 stop_bits = (cflag & CSTOPB) ? 2 : 1; |
231 |
269 |
|
270 printk(KERN_INFO PFX "Requested Data frame type %u%c%u.\n", |
|
271 data_bits, |
|
272 (par == PAR_NONE ? 'N' : (par == PAR_ODD ? 'O' : 'E')), |
|
273 stop_bits); |
|
274 |
|
275 for (i = 0; i < sizeof(el600x_data_frame) / sizeof(el600x_data_frame_t); |
|
276 i++) { |
|
277 el600x_data_frame_t *df = el600x_data_frame + i; |
|
278 if (df->data_bits == data_bits && |
|
279 df->parity == par && |
|
280 df->stop_bits == stop_bits) { |
|
281 df_to_use = df; |
|
282 break; |
|
283 } |
|
284 } |
|
285 |
|
286 if (!df_to_use) { |
|
287 printk(KERN_ERR PFX "Error: Data frame type not supported.\n"); |
|
288 return -EINVAL; |
|
289 } |
|
290 |
|
291 printk(KERN_ERR PFX "Reconfiguring.\n"); |
|
292 ser->data_frame_config = df_to_use->value; |
232 return 0; |
293 return 0; |
233 } |
294 } |
234 |
295 |
235 /****************************************************************************/ |
296 /****************************************************************************/ |
236 |
297 |