.. | .. |
---|
20 | 20 | #include <linux/module.h> |
---|
21 | 21 | #include <linux/of_graph.h> |
---|
22 | 22 | #include <linux/rk-camera-module.h> |
---|
| 23 | +#include <linux/rk_hdmirx_class.h> |
---|
23 | 24 | #include <linux/slab.h> |
---|
24 | 25 | #include <linux/timer.h> |
---|
25 | 26 | #include <linux/v4l2-dv-timings.h> |
---|
.. | .. |
---|
471 | 472 | struct regmap *mipi_regmap; |
---|
472 | 473 | struct regmap *edid_regmap; |
---|
473 | 474 | u8 attr_hdmi_reg_bank; |
---|
474 | | - struct class *hdmirx_class; |
---|
475 | 475 | struct device *dev; |
---|
476 | 476 | struct device *classdev; |
---|
477 | 477 | struct v4l2_fwnode_bus_mipi_csi2 bus; |
---|
.. | .. |
---|
3519 | 3519 | return 0; |
---|
3520 | 3520 | } |
---|
3521 | 3521 | |
---|
| 3522 | +static void it6616_detect_hot_plug(struct v4l2_subdev *sd) |
---|
| 3523 | +{ |
---|
| 3524 | + struct it6616 *it6616 = to_it6616(sd); |
---|
| 3525 | + |
---|
| 3526 | + if (it6616->mipi_tx_video_stable && it6616_hdmi_is_5v_on(it6616)) |
---|
| 3527 | + v4l2_ctrl_s_ctrl(it6616->detect_tx_5v_ctrl, 1); |
---|
| 3528 | + else |
---|
| 3529 | + v4l2_ctrl_s_ctrl(it6616->detect_tx_5v_ctrl, 0); |
---|
| 3530 | +} |
---|
| 3531 | + |
---|
3522 | 3532 | static void it6616_work_i2c_poll(struct work_struct *work) |
---|
3523 | 3533 | { |
---|
3524 | 3534 | struct delayed_work *dwork = to_delayed_work(work); |
---|
.. | .. |
---|
3526 | 3536 | struct it6616, work_i2c_poll); |
---|
3527 | 3537 | bool handled; |
---|
3528 | 3538 | |
---|
3529 | | - it6616_s_ctrl_detect_tx_5v(&it6616->sd); |
---|
3530 | 3539 | it6616_isr(&it6616->sd, 0, &handled); |
---|
| 3540 | + it6616_detect_hot_plug(&it6616->sd); |
---|
3531 | 3541 | schedule_delayed_work(&it6616->work_i2c_poll, |
---|
3532 | 3542 | msecs_to_jiffies(POLL_INTERVAL_MS)); |
---|
3533 | 3543 | } |
---|
.. | .. |
---|
4212 | 4222 | static DEVICE_ATTR_RO(audio_present); |
---|
4213 | 4223 | static DEVICE_ATTR_RO(audio_rate); |
---|
4214 | 4224 | |
---|
| 4225 | +static struct attribute *it6616_audio_attrs[] = { |
---|
| 4226 | + &dev_attr_audio_rate.attr, |
---|
| 4227 | + &dev_attr_audio_present.attr, |
---|
| 4228 | + NULL |
---|
| 4229 | +}; |
---|
| 4230 | +ATTRIBUTE_GROUPS(it6616_audio); |
---|
| 4231 | + |
---|
4215 | 4232 | static int it6616_create_class_attr(struct it6616 *it6616) |
---|
4216 | 4233 | { |
---|
4217 | | - int ret = 0; |
---|
4218 | | - |
---|
4219 | | - it6616->hdmirx_class = class_create(THIS_MODULE, "hdmirx_it6616"); |
---|
4220 | | - if (IS_ERR(it6616->hdmirx_class)) { |
---|
4221 | | - ret = -ENOMEM; |
---|
4222 | | - dev_err(it6616->dev, "failed to create hdmirx_it6616 class!\n"); |
---|
4223 | | - return ret; |
---|
4224 | | - } |
---|
4225 | | - |
---|
4226 | | - it6616->classdev = device_create(it6616->hdmirx_class, NULL, |
---|
4227 | | - MKDEV(0, 0), NULL, "hdmirx_it6616"); |
---|
4228 | | - if (IS_ERR(it6616->classdev)) { |
---|
4229 | | - ret = PTR_ERR(it6616->classdev); |
---|
4230 | | - dev_err(it6616->dev, "Failed to create device\n"); |
---|
4231 | | - goto err1; |
---|
4232 | | - } |
---|
4233 | | - |
---|
4234 | | - ret = device_create_file(it6616->classdev, |
---|
4235 | | - &dev_attr_audio_present); |
---|
4236 | | - if (ret) { |
---|
4237 | | - dev_err(it6616->dev, "failed to create attr audio_present!\n"); |
---|
4238 | | - goto err1; |
---|
4239 | | - } |
---|
4240 | | - |
---|
4241 | | - ret = device_create_file(it6616->classdev, |
---|
4242 | | - &dev_attr_audio_rate); |
---|
4243 | | - if (ret) { |
---|
4244 | | - dev_err(it6616->dev, |
---|
4245 | | - "failed to create attr audio_rate!\n"); |
---|
4246 | | - goto err; |
---|
4247 | | - } |
---|
4248 | | - |
---|
4249 | | - return ret; |
---|
4250 | | - |
---|
4251 | | -err: |
---|
4252 | | - device_remove_file(it6616->classdev, &dev_attr_audio_present); |
---|
4253 | | -err1: |
---|
4254 | | - class_destroy(it6616->hdmirx_class); |
---|
4255 | | - return ret; |
---|
| 4234 | + it6616->classdev = device_create_with_groups(rk_hdmirx_class(), |
---|
| 4235 | + it6616->dev, MKDEV(0, 0), |
---|
| 4236 | + it6616, |
---|
| 4237 | + it6616_audio_groups, |
---|
| 4238 | + "it6616"); |
---|
| 4239 | + if (IS_ERR(it6616->classdev)) |
---|
| 4240 | + return IS_ERR(it6616->classdev); |
---|
| 4241 | + return 0; |
---|
4256 | 4242 | } |
---|
4257 | 4243 | |
---|
4258 | 4244 | static void it6616_remove_class_attr(struct it6616 *it6616) |
---|
4259 | 4245 | { |
---|
4260 | 4246 | device_remove_file(it6616->classdev, &dev_attr_audio_rate); |
---|
4261 | 4247 | device_remove_file(it6616->classdev, &dev_attr_audio_present); |
---|
4262 | | - class_destroy(it6616->hdmirx_class); |
---|
4263 | 4248 | } |
---|
4264 | 4249 | |
---|
4265 | 4250 | static int it6616_probe(struct i2c_client *client, |
---|