diff options
author | Laurent Pinchart <laurent.pinchart@ideasonboard.com> | 2014-01-01 12:40:35 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@osg.samsung.com> | 2015-04-02 20:31:31 -0400 |
commit | f2272e1347c452fb6cc4cb6eeea8b7266cc87ae5 (patch) | |
tree | 573d1b7123785205ce34a27b5576232ddea6863c /drivers/media/i2c | |
parent | 5888f9df0dcd5eb3479345301e0a35a19fcb52a9 (diff) |
[media] v4l: mt9v032: Add OF support
Parse DT properties into a platform data structure when a DT node is
available.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Acked-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
Diffstat (limited to 'drivers/media/i2c')
-rw-r--r-- | drivers/media/i2c/mt9v032.c | 69 |
1 files changed, 68 insertions, 1 deletions
diff --git a/drivers/media/i2c/mt9v032.c b/drivers/media/i2c/mt9v032.c index 6d64e23b1f94..977f4006edbd 100644 --- a/drivers/media/i2c/mt9v032.c +++ b/drivers/media/i2c/mt9v032.c | |||
@@ -17,6 +17,8 @@ | |||
17 | #include <linux/i2c.h> | 17 | #include <linux/i2c.h> |
18 | #include <linux/log2.h> | 18 | #include <linux/log2.h> |
19 | #include <linux/mutex.h> | 19 | #include <linux/mutex.h> |
20 | #include <linux/of.h> | ||
21 | #include <linux/of_gpio.h> | ||
20 | #include <linux/regmap.h> | 22 | #include <linux/regmap.h> |
21 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
22 | #include <linux/videodev2.h> | 24 | #include <linux/videodev2.h> |
@@ -26,6 +28,7 @@ | |||
26 | #include <media/mt9v032.h> | 28 | #include <media/mt9v032.h> |
27 | #include <media/v4l2-ctrls.h> | 29 | #include <media/v4l2-ctrls.h> |
28 | #include <media/v4l2-device.h> | 30 | #include <media/v4l2-device.h> |
31 | #include <media/v4l2-of.h> | ||
29 | #include <media/v4l2-subdev.h> | 32 | #include <media/v4l2-subdev.h> |
30 | 33 | ||
31 | /* The first four rows are black rows. The active area spans 753x481 pixels. */ | 34 | /* The first four rows are black rows. The active area spans 753x481 pixels. */ |
@@ -876,10 +879,58 @@ static const struct regmap_config mt9v032_regmap_config = { | |||
876 | * Driver initialization and probing | 879 | * Driver initialization and probing |
877 | */ | 880 | */ |
878 | 881 | ||
882 | static struct mt9v032_platform_data * | ||
883 | mt9v032_get_pdata(struct i2c_client *client) | ||
884 | { | ||
885 | struct mt9v032_platform_data *pdata; | ||
886 | struct v4l2_of_endpoint endpoint; | ||
887 | struct device_node *np; | ||
888 | struct property *prop; | ||
889 | |||
890 | if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node) | ||
891 | return client->dev.platform_data; | ||
892 | |||
893 | np = of_graph_get_next_endpoint(client->dev.of_node, NULL); | ||
894 | if (!np) | ||
895 | return NULL; | ||
896 | |||
897 | if (v4l2_of_parse_endpoint(np, &endpoint) < 0) | ||
898 | goto done; | ||
899 | |||
900 | pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL); | ||
901 | if (!pdata) | ||
902 | goto done; | ||
903 | |||
904 | prop = of_find_property(np, "link-frequencies", NULL); | ||
905 | if (prop) { | ||
906 | u64 *link_freqs; | ||
907 | size_t size = prop->length / sizeof(*link_freqs); | ||
908 | |||
909 | link_freqs = devm_kcalloc(&client->dev, size, | ||
910 | sizeof(*link_freqs), GFP_KERNEL); | ||
911 | if (!link_freqs) | ||
912 | goto done; | ||
913 | |||
914 | if (of_property_read_u64_array(np, "link-frequencies", | ||
915 | link_freqs, size) < 0) | ||
916 | goto done; | ||
917 | |||
918 | pdata->link_freqs = link_freqs; | ||
919 | pdata->link_def_freq = link_freqs[0]; | ||
920 | } | ||
921 | |||
922 | pdata->clk_pol = !!(endpoint.bus.parallel.flags & | ||
923 | V4L2_MBUS_PCLK_SAMPLE_RISING); | ||
924 | |||
925 | done: | ||
926 | of_node_put(np); | ||
927 | return pdata; | ||
928 | } | ||
929 | |||
879 | static int mt9v032_probe(struct i2c_client *client, | 930 | static int mt9v032_probe(struct i2c_client *client, |
880 | const struct i2c_device_id *did) | 931 | const struct i2c_device_id *did) |
881 | { | 932 | { |
882 | struct mt9v032_platform_data *pdata = client->dev.platform_data; | 933 | struct mt9v032_platform_data *pdata = mt9v032_get_pdata(client); |
883 | struct mt9v032 *mt9v032; | 934 | struct mt9v032 *mt9v032; |
884 | unsigned int i; | 935 | unsigned int i; |
885 | int ret; | 936 | int ret; |
@@ -1037,9 +1088,25 @@ static const struct i2c_device_id mt9v032_id[] = { | |||
1037 | }; | 1088 | }; |
1038 | MODULE_DEVICE_TABLE(i2c, mt9v032_id); | 1089 | MODULE_DEVICE_TABLE(i2c, mt9v032_id); |
1039 | 1090 | ||
1091 | #if IS_ENABLED(CONFIG_OF) | ||
1092 | static const struct of_device_id mt9v032_of_match[] = { | ||
1093 | { .compatible = "aptina,mt9v022" }, | ||
1094 | { .compatible = "aptina,mt9v022m" }, | ||
1095 | { .compatible = "aptina,mt9v024" }, | ||
1096 | { .compatible = "aptina,mt9v024m" }, | ||
1097 | { .compatible = "aptina,mt9v032" }, | ||
1098 | { .compatible = "aptina,mt9v032m" }, | ||
1099 | { .compatible = "aptina,mt9v034" }, | ||
1100 | { .compatible = "aptina,mt9v034m" }, | ||
1101 | { /* Sentinel */ } | ||
1102 | }; | ||
1103 | MODULE_DEVICE_TABLE(of, mt9v032_of_match); | ||
1104 | #endif | ||
1105 | |||
1040 | static struct i2c_driver mt9v032_driver = { | 1106 | static struct i2c_driver mt9v032_driver = { |
1041 | .driver = { | 1107 | .driver = { |
1042 | .name = "mt9v032", | 1108 | .name = "mt9v032", |
1109 | .of_match_table = of_match_ptr(mt9v032_of_match), | ||
1043 | }, | 1110 | }, |
1044 | .probe = mt9v032_probe, | 1111 | .probe = mt9v032_probe, |
1045 | .remove = mt9v032_remove, | 1112 | .remove = mt9v032_remove, |