0001
0002
0003
0004
0005
0006
0007
0008 #ifndef _MEDIA_CEC_H
0009 #define _MEDIA_CEC_H
0010
0011 #include <linux/poll.h>
0012 #include <linux/fs.h>
0013 #include <linux/debugfs.h>
0014 #include <linux/device.h>
0015 #include <linux/cdev.h>
0016 #include <linux/kthread.h>
0017 #include <linux/timer.h>
0018 #include <linux/cec-funcs.h>
0019 #include <media/rc-core.h>
0020
0021 #define CEC_CAP_DEFAULTS (CEC_CAP_LOG_ADDRS | CEC_CAP_TRANSMIT | \
0022 CEC_CAP_PASSTHROUGH | CEC_CAP_RC)
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043 struct cec_devnode {
0044
0045 struct device dev;
0046 struct cdev cdev;
0047
0048
0049 int minor;
0050
0051 struct mutex lock;
0052 bool registered;
0053 bool unregistered;
0054
0055 struct mutex lock_fhs;
0056 struct list_head fhs;
0057 };
0058
0059 struct cec_adapter;
0060 struct cec_data;
0061 struct cec_pin;
0062 struct cec_notifier;
0063
0064 struct cec_data {
0065 struct list_head list;
0066 struct list_head xfer_list;
0067 struct cec_adapter *adap;
0068 struct cec_msg msg;
0069 struct cec_fh *fh;
0070 struct delayed_work work;
0071 struct completion c;
0072 u8 attempts;
0073 bool blocking;
0074 bool completed;
0075 };
0076
0077 struct cec_msg_entry {
0078 struct list_head list;
0079 struct cec_msg msg;
0080 };
0081
0082 struct cec_event_entry {
0083 struct list_head list;
0084 struct cec_event ev;
0085 };
0086
0087 #define CEC_NUM_CORE_EVENTS 2
0088 #define CEC_NUM_EVENTS CEC_EVENT_PIN_5V_HIGH
0089
0090 struct cec_fh {
0091 struct list_head list;
0092 struct list_head xfer_list;
0093 struct cec_adapter *adap;
0094 u8 mode_initiator;
0095 u8 mode_follower;
0096
0097
0098 wait_queue_head_t wait;
0099 struct mutex lock;
0100 struct list_head events[CEC_NUM_EVENTS];
0101 u16 queued_events[CEC_NUM_EVENTS];
0102 unsigned int total_queued_events;
0103 struct cec_event_entry core_events[CEC_NUM_CORE_EVENTS];
0104 struct list_head msgs;
0105 unsigned int queued_msgs;
0106 };
0107
0108 #define CEC_SIGNAL_FREE_TIME_RETRY 3
0109 #define CEC_SIGNAL_FREE_TIME_NEW_INITIATOR 5
0110 #define CEC_SIGNAL_FREE_TIME_NEXT_XFER 7
0111
0112
0113 #define CEC_FREE_TIME_TO_USEC(ft) ((ft) * 2400)
0114
0115 struct cec_adap_ops {
0116
0117 int (*adap_enable)(struct cec_adapter *adap, bool enable);
0118 int (*adap_monitor_all_enable)(struct cec_adapter *adap, bool enable);
0119 int (*adap_monitor_pin_enable)(struct cec_adapter *adap, bool enable);
0120 int (*adap_log_addr)(struct cec_adapter *adap, u8 logical_addr);
0121 void (*adap_configured)(struct cec_adapter *adap, bool configured);
0122 int (*adap_transmit)(struct cec_adapter *adap, u8 attempts,
0123 u32 signal_free_time, struct cec_msg *msg);
0124 void (*adap_status)(struct cec_adapter *adap, struct seq_file *file);
0125 void (*adap_free)(struct cec_adapter *adap);
0126
0127
0128 int (*error_inj_show)(struct cec_adapter *adap, struct seq_file *sf);
0129 bool (*error_inj_parse_line)(struct cec_adapter *adap, char *line);
0130
0131
0132 int (*received)(struct cec_adapter *adap, struct cec_msg *msg);
0133 };
0134
0135
0136
0137
0138
0139
0140
0141
0142
0143
0144
0145 #define CEC_MAX_MSG_RX_QUEUE_SZ (18 * 3)
0146
0147
0148
0149
0150
0151
0152
0153 #define CEC_MAX_MSG_TX_QUEUE_SZ (18 * 1)
0154
0155
0156
0157
0158
0159
0160
0161
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183
0184
0185
0186
0187
0188
0189
0190
0191
0192
0193
0194
0195
0196
0197
0198
0199
0200
0201
0202
0203
0204
0205
0206
0207
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217
0218 struct cec_adapter {
0219 struct module *owner;
0220 char name[32];
0221 struct cec_devnode devnode;
0222 struct mutex lock;
0223 struct rc_dev *rc;
0224
0225 struct list_head transmit_queue;
0226 unsigned int transmit_queue_sz;
0227 struct list_head wait_queue;
0228 struct cec_data *transmitting;
0229 bool transmit_in_progress;
0230 bool transmit_in_progress_aborted;
0231 unsigned int xfer_timeout_ms;
0232
0233 struct task_struct *kthread_config;
0234 struct completion config_completion;
0235
0236 struct task_struct *kthread;
0237 wait_queue_head_t kthread_waitq;
0238
0239 const struct cec_adap_ops *ops;
0240 void *priv;
0241 u32 capabilities;
0242 u8 available_log_addrs;
0243
0244 u16 phys_addr;
0245 bool needs_hpd;
0246 bool is_enabled;
0247 bool is_configuring;
0248 bool must_reconfigure;
0249 bool is_configured;
0250 bool cec_pin_is_high;
0251 bool adap_controls_phys_addr;
0252 u8 last_initiator;
0253 u32 monitor_all_cnt;
0254 u32 monitor_pin_cnt;
0255 u32 follower_cnt;
0256 struct cec_fh *cec_follower;
0257 struct cec_fh *cec_initiator;
0258 bool passthrough;
0259 struct cec_log_addrs log_addrs;
0260 struct cec_connector_info conn_info;
0261
0262 u32 tx_timeouts;
0263
0264 #ifdef CONFIG_CEC_NOTIFIER
0265 struct cec_notifier *notifier;
0266 #endif
0267 #ifdef CONFIG_CEC_PIN
0268 struct cec_pin *pin;
0269 #endif
0270
0271 struct dentry *cec_dir;
0272
0273 u32 sequence;
0274
0275 char input_phys[32];
0276 };
0277
0278 static inline void *cec_get_drvdata(const struct cec_adapter *adap)
0279 {
0280 return adap->priv;
0281 }
0282
0283 static inline bool cec_has_log_addr(const struct cec_adapter *adap, u8 log_addr)
0284 {
0285 return adap->log_addrs.log_addr_mask & (1 << log_addr);
0286 }
0287
0288 static inline bool cec_is_sink(const struct cec_adapter *adap)
0289 {
0290 return adap->phys_addr == 0;
0291 }
0292
0293
0294
0295
0296
0297
0298
0299
0300 static inline bool cec_is_registered(const struct cec_adapter *adap)
0301 {
0302 return adap && adap->devnode.registered;
0303 }
0304
0305 #define cec_phys_addr_exp(pa) \
0306 ((pa) >> 12), ((pa) >> 8) & 0xf, ((pa) >> 4) & 0xf, (pa) & 0xf
0307
0308 struct edid;
0309 struct drm_connector;
0310
0311 #if IS_REACHABLE(CONFIG_CEC_CORE)
0312 struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops,
0313 void *priv, const char *name, u32 caps, u8 available_las);
0314 int cec_register_adapter(struct cec_adapter *adap, struct device *parent);
0315 void cec_unregister_adapter(struct cec_adapter *adap);
0316 void cec_delete_adapter(struct cec_adapter *adap);
0317
0318 int cec_s_log_addrs(struct cec_adapter *adap, struct cec_log_addrs *log_addrs,
0319 bool block);
0320 void cec_s_phys_addr(struct cec_adapter *adap, u16 phys_addr,
0321 bool block);
0322 void cec_s_phys_addr_from_edid(struct cec_adapter *adap,
0323 const struct edid *edid);
0324 void cec_s_conn_info(struct cec_adapter *adap,
0325 const struct cec_connector_info *conn_info);
0326 int cec_transmit_msg(struct cec_adapter *adap, struct cec_msg *msg,
0327 bool block);
0328
0329
0330 void cec_transmit_done_ts(struct cec_adapter *adap, u8 status,
0331 u8 arb_lost_cnt, u8 nack_cnt, u8 low_drive_cnt,
0332 u8 error_cnt, ktime_t ts);
0333
0334 static inline void cec_transmit_done(struct cec_adapter *adap, u8 status,
0335 u8 arb_lost_cnt, u8 nack_cnt,
0336 u8 low_drive_cnt, u8 error_cnt)
0337 {
0338 cec_transmit_done_ts(adap, status, arb_lost_cnt, nack_cnt,
0339 low_drive_cnt, error_cnt, ktime_get());
0340 }
0341
0342
0343
0344
0345
0346 void cec_transmit_attempt_done_ts(struct cec_adapter *adap,
0347 u8 status, ktime_t ts);
0348
0349 static inline void cec_transmit_attempt_done(struct cec_adapter *adap,
0350 u8 status)
0351 {
0352 cec_transmit_attempt_done_ts(adap, status, ktime_get());
0353 }
0354
0355 void cec_received_msg_ts(struct cec_adapter *adap,
0356 struct cec_msg *msg, ktime_t ts);
0357
0358 static inline void cec_received_msg(struct cec_adapter *adap,
0359 struct cec_msg *msg)
0360 {
0361 cec_received_msg_ts(adap, msg, ktime_get());
0362 }
0363
0364
0365
0366
0367
0368
0369
0370
0371
0372
0373 void cec_queue_pin_cec_event(struct cec_adapter *adap, bool is_high,
0374 bool dropped_events, ktime_t ts);
0375
0376
0377
0378
0379
0380
0381
0382
0383
0384 void cec_queue_pin_hpd_event(struct cec_adapter *adap, bool is_high, ktime_t ts);
0385
0386
0387
0388
0389
0390
0391
0392
0393
0394 void cec_queue_pin_5v_event(struct cec_adapter *adap, bool is_high, ktime_t ts);
0395
0396
0397
0398
0399
0400
0401
0402
0403
0404
0405
0406
0407 u16 cec_get_edid_phys_addr(const u8 *edid, unsigned int size,
0408 unsigned int *offset);
0409
0410 void cec_fill_conn_info_from_drm(struct cec_connector_info *conn_info,
0411 const struct drm_connector *connector);
0412
0413 #else
0414
0415 static inline int cec_register_adapter(struct cec_adapter *adap,
0416 struct device *parent)
0417 {
0418 return 0;
0419 }
0420
0421 static inline void cec_unregister_adapter(struct cec_adapter *adap)
0422 {
0423 }
0424
0425 static inline void cec_delete_adapter(struct cec_adapter *adap)
0426 {
0427 }
0428
0429 static inline void cec_s_phys_addr(struct cec_adapter *adap, u16 phys_addr,
0430 bool block)
0431 {
0432 }
0433
0434 static inline void cec_s_phys_addr_from_edid(struct cec_adapter *adap,
0435 const struct edid *edid)
0436 {
0437 }
0438
0439 static inline u16 cec_get_edid_phys_addr(const u8 *edid, unsigned int size,
0440 unsigned int *offset)
0441 {
0442 if (offset)
0443 *offset = 0;
0444 return CEC_PHYS_ADDR_INVALID;
0445 }
0446
0447 static inline void cec_s_conn_info(struct cec_adapter *adap,
0448 const struct cec_connector_info *conn_info)
0449 {
0450 }
0451
0452 static inline void
0453 cec_fill_conn_info_from_drm(struct cec_connector_info *conn_info,
0454 const struct drm_connector *connector)
0455 {
0456 memset(conn_info, 0, sizeof(*conn_info));
0457 }
0458
0459 #endif
0460
0461
0462
0463
0464
0465
0466
0467
0468
0469 static inline void cec_phys_addr_invalidate(struct cec_adapter *adap)
0470 {
0471 cec_s_phys_addr(adap, CEC_PHYS_ADDR_INVALID, false);
0472 }
0473
0474
0475
0476
0477
0478
0479
0480
0481
0482
0483
0484
0485
0486
0487
0488
0489
0490 static inline unsigned int cec_get_edid_spa_location(const u8 *edid,
0491 unsigned int size)
0492 {
0493 unsigned int blocks = size / 128;
0494 unsigned int block;
0495 u8 d;
0496
0497
0498 if (blocks < 2 || size % 128)
0499 return 0;
0500
0501
0502
0503
0504
0505
0506
0507
0508 if (edid[0x7e] + 1 < blocks)
0509 blocks = edid[0x7e] + 1;
0510
0511 for (block = 1; block < blocks; block++) {
0512 unsigned int offset = block * 128;
0513
0514
0515 if (edid[offset] != 0x02 || edid[offset + 1] != 0x03)
0516 continue;
0517
0518
0519 d = edid[offset + 2] & 0x7f;
0520
0521 if (d <= 4)
0522 continue;
0523 if (d > 4) {
0524 unsigned int i = offset + 4;
0525 unsigned int end = offset + d;
0526
0527
0528 do {
0529 u8 tag = edid[i] >> 5;
0530 u8 len = edid[i] & 0x1f;
0531
0532 if (tag == 3 && len >= 5 && i + len <= end &&
0533 edid[i + 1] == 0x03 &&
0534 edid[i + 2] == 0x0c &&
0535 edid[i + 3] == 0x00)
0536 return i + 4;
0537 i += len + 1;
0538 } while (i < end);
0539 }
0540 }
0541 return 0;
0542 }
0543
0544 #endif