blob: 05ae7cc95ddf5ffb09cd60260ce2159c9442dbc7 [file] [log] [blame]
Rajakumar Govindaram7d2b9772017-07-19 15:16:12 -07001/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12
13#include <linux/module.h>
14#include <linux/slab.h>
15#include <linux/mod_devicetable.h>
16#include <linux/of_device.h>
17#include <linux/timer.h>
18
19#include "jpeg_dma_core.h"
20#include "jpeg_dma_soc.h"
21#include "cam_hw.h"
22#include "cam_hw_intf.h"
23#include "cam_io_util.h"
24#include "cam_jpeg_hw_intf.h"
25#include "cam_jpeg_hw_mgr_intf.h"
26#include "cam_cpas_api.h"
27#include "cam_debug_util.h"
28
29static struct cam_jpeg_dma_device_hw_info cam_jpeg_dma_hw_info = {
30 .reserved = 0,
31};
32EXPORT_SYMBOL(cam_jpeg_dma_hw_info);
33
34static int cam_jpeg_dma_register_cpas(struct cam_hw_soc_info *soc_info,
35 struct cam_jpeg_dma_device_core_info *core_info,
36 uint32_t hw_idx)
37{
38 struct cam_cpas_register_params cpas_register_params;
39 int rc;
40
Jigarkumar Zalab7b49f12017-08-21 16:45:38 -070041 cpas_register_params.dev = soc_info->dev;
Rajakumar Govindaram7d2b9772017-07-19 15:16:12 -070042 memcpy(cpas_register_params.identifier, "jpeg-dma",
43 sizeof("jpeg-dma"));
44 cpas_register_params.cam_cpas_client_cb = NULL;
45 cpas_register_params.cell_index = hw_idx;
46 cpas_register_params.userdata = NULL;
47
48 rc = cam_cpas_register_client(&cpas_register_params);
49 if (rc) {
50 CAM_ERR(CAM_JPEG, "cpas_register failed: %d", rc);
51 return rc;
52 }
53 core_info->cpas_handle = cpas_register_params.client_handle;
54
55 return rc;
56}
57
58static int cam_jpeg_dma_unregister_cpas(
59 struct cam_jpeg_dma_device_core_info *core_info)
60{
61 int rc;
62
63 rc = cam_cpas_unregister_client(core_info->cpas_handle);
64 if (rc)
65 CAM_ERR(CAM_JPEG, "cpas unregister failed: %d", rc);
66 core_info->cpas_handle = 0;
67
68 return rc;
69}
70
71static int cam_jpeg_dma_remove(struct platform_device *pdev)
72{
73 struct cam_hw_info *jpeg_dma_dev = NULL;
74 struct cam_hw_intf *jpeg_dma_dev_intf = NULL;
75 struct cam_jpeg_dma_device_core_info *core_info = NULL;
76 int rc;
77
78 jpeg_dma_dev_intf = platform_get_drvdata(pdev);
79 if (!jpeg_dma_dev_intf) {
80 CAM_ERR(CAM_JPEG, "error No data in pdev");
81 return -EINVAL;
82 }
83
84 jpeg_dma_dev = jpeg_dma_dev_intf->hw_priv;
85 if (!jpeg_dma_dev) {
86 CAM_ERR(CAM_JPEG, "error HW data is NULL");
87 rc = -ENODEV;
88 goto free_jpeg_hw_intf;
89 }
90
91 core_info = (struct cam_jpeg_dma_device_core_info *)
92 jpeg_dma_dev->core_info;
93 if (!core_info) {
94 CAM_ERR(CAM_JPEG, "error core data NULL");
95 goto deinit_soc;
96 }
97
98 rc = cam_jpeg_dma_unregister_cpas(core_info);
99 if (rc)
100 CAM_ERR(CAM_JPEG, " unreg failed to reg cpas %d", rc);
101
Rajakumar Govindaram2264d152017-09-11 10:53:31 -0700102 mutex_destroy(&core_info->core_mutex);
Rajakumar Govindaram7d2b9772017-07-19 15:16:12 -0700103 kfree(core_info);
104
105deinit_soc:
106 rc = cam_soc_util_release_platform_resource(&jpeg_dma_dev->soc_info);
107 if (rc)
108 CAM_ERR(CAM_JPEG, "Failed to deinit soc rc=%d", rc);
109
110 mutex_destroy(&jpeg_dma_dev->hw_mutex);
111 kfree(jpeg_dma_dev);
112
113free_jpeg_hw_intf:
114 kfree(jpeg_dma_dev_intf);
115 return rc;
116}
117
118static int cam_jpeg_dma_probe(struct platform_device *pdev)
119{
120 struct cam_hw_info *jpeg_dma_dev = NULL;
121 struct cam_hw_intf *jpeg_dma_dev_intf = NULL;
122 const struct of_device_id *match_dev = NULL;
123 struct cam_jpeg_dma_device_core_info *core_info = NULL;
124 struct cam_jpeg_dma_device_hw_info *hw_info = NULL;
125 int rc;
126
127 jpeg_dma_dev_intf = kzalloc(sizeof(struct cam_hw_intf), GFP_KERNEL);
128 if (!jpeg_dma_dev_intf)
129 return -ENOMEM;
130
131 of_property_read_u32(pdev->dev.of_node,
132 "cell-index", &jpeg_dma_dev_intf->hw_idx);
133
134 jpeg_dma_dev = kzalloc(sizeof(struct cam_hw_info), GFP_KERNEL);
135 if (!jpeg_dma_dev) {
136 rc = -ENOMEM;
137 goto error_alloc_dev;
138 }
139 jpeg_dma_dev->soc_info.pdev = pdev;
Jigarkumar Zalab7b49f12017-08-21 16:45:38 -0700140 jpeg_dma_dev->soc_info.dev = &pdev->dev;
141 jpeg_dma_dev->soc_info.dev_name = pdev->name;
Rajakumar Govindaram7d2b9772017-07-19 15:16:12 -0700142 jpeg_dma_dev_intf->hw_priv = jpeg_dma_dev;
143 jpeg_dma_dev_intf->hw_ops.init = cam_jpeg_dma_init_hw;
144 jpeg_dma_dev_intf->hw_ops.deinit = cam_jpeg_dma_deinit_hw;
145 jpeg_dma_dev_intf->hw_ops.process_cmd = cam_jpeg_dma_process_cmd;
146 jpeg_dma_dev_intf->hw_type = CAM_JPEG_DEV_DMA;
147
148 platform_set_drvdata(pdev, jpeg_dma_dev_intf);
149 jpeg_dma_dev->core_info =
150 kzalloc(sizeof(struct cam_jpeg_dma_device_core_info),
151 GFP_KERNEL);
152 if (!jpeg_dma_dev->core_info) {
153 rc = -ENOMEM;
154 goto error_alloc_core;
155 }
156 core_info = (struct cam_jpeg_dma_device_core_info *)jpeg_dma_dev->
157 core_info;
158
159 match_dev = of_match_device(pdev->dev.driver->of_match_table,
160 &pdev->dev);
161 if (!match_dev) {
162 CAM_ERR(CAM_JPEG, " No jpeg_dma hardware info");
163 rc = -EINVAL;
164 goto error_match_dev;
165 }
166 hw_info = (struct cam_jpeg_dma_device_hw_info *)match_dev->data;
167 core_info->jpeg_dma_hw_info = hw_info;
168 core_info->core_state = CAM_JPEG_DMA_CORE_NOT_READY;
Rajakumar Govindaram2264d152017-09-11 10:53:31 -0700169 mutex_init(&core_info->core_mutex);
Rajakumar Govindaram7d2b9772017-07-19 15:16:12 -0700170
171 rc = cam_jpeg_dma_init_soc_resources(&jpeg_dma_dev->soc_info,
172 cam_jpeg_dma_irq,
173 jpeg_dma_dev);
174 if (rc) {
Jigarkumar Zala3865c1c2017-11-28 12:08:50 -0800175 CAM_ERR(CAM_JPEG, "failed to init_soc %d", rc);
Rajakumar Govindaram2264d152017-09-11 10:53:31 -0700176 goto error_init_soc;
Rajakumar Govindaram7d2b9772017-07-19 15:16:12 -0700177 }
178
179 rc = cam_jpeg_dma_register_cpas(&jpeg_dma_dev->soc_info,
180 core_info, jpeg_dma_dev_intf->hw_idx);
181 if (rc) {
182 CAM_ERR(CAM_JPEG, " failed to reg cpas %d", rc);
183 goto error_reg_cpas;
184 }
185 jpeg_dma_dev->hw_state = CAM_HW_STATE_POWER_DOWN;
186 mutex_init(&jpeg_dma_dev->hw_mutex);
187 spin_lock_init(&jpeg_dma_dev->hw_lock);
188 init_completion(&jpeg_dma_dev->hw_complete);
189
190 CAM_DBG(CAM_JPEG, " hwidx %d", jpeg_dma_dev_intf->hw_idx);
191
192 return rc;
193
194error_reg_cpas:
195 rc = cam_soc_util_release_platform_resource(&jpeg_dma_dev->soc_info);
Rajakumar Govindaram2264d152017-09-11 10:53:31 -0700196error_init_soc:
197 mutex_destroy(&core_info->core_mutex);
Rajakumar Govindaram7d2b9772017-07-19 15:16:12 -0700198error_match_dev:
199 kfree(jpeg_dma_dev->core_info);
200error_alloc_core:
201 kfree(jpeg_dma_dev);
202error_alloc_dev:
203 kfree(jpeg_dma_dev_intf);
204 return rc;
205}
206
207static const struct of_device_id cam_jpeg_dma_dt_match[] = {
208 {
209 .compatible = "qcom,cam_jpeg_dma",
210 .data = &cam_jpeg_dma_hw_info,
211 },
212 {}
213};
214MODULE_DEVICE_TABLE(of, cam_jpeg_dma_dt_match);
215
216static struct platform_driver cam_jpeg_dma_driver = {
217 .probe = cam_jpeg_dma_probe,
218 .remove = cam_jpeg_dma_remove,
219 .driver = {
220 .name = "cam-jpeg-dma",
221 .owner = THIS_MODULE,
222 .of_match_table = cam_jpeg_dma_dt_match,
223 },
224};
225
226static int __init cam_jpeg_dma_init_module(void)
227{
228 return platform_driver_register(&cam_jpeg_dma_driver);
229}
230
231static void __exit cam_jpeg_dma_exit_module(void)
232{
233 platform_driver_unregister(&cam_jpeg_dma_driver);
234}
235
236module_init(cam_jpeg_dma_init_module);
237module_exit(cam_jpeg_dma_exit_module);
238MODULE_DESCRIPTION("CAM JPEG_DMA driver");
239MODULE_LICENSE("GPL v2");