|
@@ -165,3 +165,88 @@ int s3c_adc_start(struct s3c_adc_client *client,
|
|
|
}
|
|
|
|
|
|
client->channel = channel;
|
|
|
+ client->nr_samples = nr_samples;
|
|
|
+
|
|
|
+ if (client->is_ts)
|
|
|
+ adc->ts_pend = client;
|
|
|
+ else
|
|
|
+ list_add_tail(&client->pend, &adc_pending);
|
|
|
+
|
|
|
+ if (!adc->cur)
|
|
|
+ s3c_adc_try(adc);
|
|
|
+
|
|
|
+ spin_unlock_irqrestore(&adc->lock, flags);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+EXPORT_SYMBOL_GPL(s3c_adc_start);
|
|
|
+
|
|
|
+static void s3c_convert_done(struct s3c_adc_client *client,
|
|
|
+ unsigned v, unsigned u, unsigned *left)
|
|
|
+{
|
|
|
+ client->result = v;
|
|
|
+ wake_up(client->wait);
|
|
|
+}
|
|
|
+
|
|
|
+int s3c_adc_read(struct s3c_adc_client *client, unsigned int ch)
|
|
|
+{
|
|
|
+ DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wake);
|
|
|
+ int ret;
|
|
|
+
|
|
|
+ client->convert_cb = s3c_convert_done;
|
|
|
+ client->wait = &wake;
|
|
|
+ client->result = -1;
|
|
|
+
|
|
|
+ ret = s3c_adc_start(client, ch, 1);
|
|
|
+ if (ret < 0)
|
|
|
+ goto err;
|
|
|
+
|
|
|
+ ret = wait_event_timeout(wake, client->result >= 0, HZ / 2);
|
|
|
+ if (client->result < 0) {
|
|
|
+ ret = -ETIMEDOUT;
|
|
|
+ goto err;
|
|
|
+ }
|
|
|
+
|
|
|
+ client->convert_cb = NULL;
|
|
|
+ return client->result;
|
|
|
+
|
|
|
+err:
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+EXPORT_SYMBOL_GPL(s3c_adc_read);
|
|
|
+
|
|
|
+static void s3c_adc_default_select(struct s3c_adc_client *client,
|
|
|
+ unsigned select)
|
|
|
+{
|
|
|
+}
|
|
|
+
|
|
|
+struct s3c_adc_client *s3c_adc_register(struct platform_device *pdev,
|
|
|
+ void (*select)(struct s3c_adc_client *client,
|
|
|
+ unsigned int selected),
|
|
|
+ void (*conv)(struct s3c_adc_client *client,
|
|
|
+ unsigned d0, unsigned d1,
|
|
|
+ unsigned *samples_left),
|
|
|
+ unsigned int is_ts)
|
|
|
+{
|
|
|
+ struct s3c_adc_client *client;
|
|
|
+
|
|
|
+ WARN_ON(!pdev);
|
|
|
+
|
|
|
+ if (!select)
|
|
|
+ select = s3c_adc_default_select;
|
|
|
+
|
|
|
+ if (!pdev)
|
|
|
+ return ERR_PTR(-EINVAL);
|
|
|
+
|
|
|
+ client = kzalloc(sizeof(struct s3c_adc_client), GFP_KERNEL);
|
|
|
+ if (!client) {
|
|
|
+ dev_err(&pdev->dev, "no memory for adc client\n");
|
|
|
+ return ERR_PTR(-ENOMEM);
|
|
|
+ }
|
|
|
+
|
|
|
+ client->pdev = pdev;
|
|
|
+ client->is_ts = is_ts;
|
|
|
+ client->select_cb = select;
|
|
|
+ client->convert_cb = conv;
|
|
|
+
|
|
|
+ return client;
|